培全 發表於 2021-9-29 13:24:00

PHP 单页面在线聊天

<p>使用PHP做的单页面在线聊天。</p>
<p>基本功能:</p>
<p>1. 多人聊天<br>2. 多房间<br>3. 传输信息加密,基于base64+字符替换实现<br>4. 基于长连接读取(ngnix使用PHP sleep有问题)<br>5. 支持昵称自定义,并使用浏览器保存。<br>6. 需要在程序目录创建chat_data文件夹,用来存储历史聊天数据(仅保留最近1分钟)</p>
<p>原代码如下:</p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 系统入口</span>
date_default_timezone_set("PRC"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">error_reporting</span>(<span style="color: rgba(255, 0, 255, 1)">E_ALL</span> &amp; ~<span style="color: rgba(255, 0, 255, 1)">E_NOTICE</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">set_time_limit</span>(30<span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(128, 0, 128, 1)">$room</span> = <span style="color: rgba(128, 0, 128, 1)">$_REQUEST</span>['room'] ?? 'default'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$type</span> = <span style="color: rgba(128, 0, 128, 1)">$_REQUEST</span>['type'] ?? 'enter'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$type</span> = <span style="color: rgba(0, 128, 128, 1)">strtolower</span>(<span style="color: rgba(128, 0, 128, 1)">$type</span><span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建新房间</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> newRoom(<span style="color: rgba(128, 0, 128, 1)">$room</span><span style="color: rgba(0, 0, 0, 1)">)
{
    </span><span style="color: rgba(128, 0, 128, 1)">$room_file</span> = './chat_data/' . <span style="color: rgba(128, 0, 128, 1)">$room</span> . '.txt'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(128, 0, 128, 1)">$key_list</span> = <span style="color: rgba(0, 128, 128, 1)">array_merge</span>(<span style="color: rgba(0, 128, 128, 1)">range</span>(48, 57), <span style="color: rgba(0, 128, 128, 1)">range</span>(65, 90), <span style="color: rgba(0, 128, 128, 1)">range</span>(97, 122), );
    </span><span style="color: rgba(128, 0, 128, 1)">$key1_list</span> = <span style="color: rgba(128, 0, 128, 1)">$key_list</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 128, 1)">shuffle</span>(<span style="color: rgba(128, 0, 128, 1)">$key1_list</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(128, 0, 128, 1)">$room_data</span> =<span style="color: rgba(0, 0, 0, 1)"> [
      </span>'name'   =&gt; <span style="color: rgba(128, 0, 128, 1)">$room</span>,
      'encode' =&gt; <span style="color: rgba(0, 128, 128, 1)">array_combine</span>(<span style="color: rgba(128, 0, 128, 1)">$key_list</span>, <span style="color: rgba(128, 0, 128, 1)">$key1_list</span>),
      'list'   =&gt; [],
      'time'   =&gt; <span style="color: rgba(0, 128, 128, 1)">date</span>('Y-m-d H:i:s'),<span style="color: rgba(0, 0, 0, 1)">
    ];
    </span><span style="color: rgba(0, 128, 128, 1)">file_put_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$room_file</span>, json_encode(<span style="color: rgba(128, 0, 128, 1)">$room_data</span><span style="color: rgba(0, 0, 0, 1)">));
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取消息列表</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> getMsg(<span style="color: rgba(128, 0, 128, 1)">$room</span>, <span style="color: rgba(128, 0, 128, 1)">$last_id</span><span style="color: rgba(0, 0, 0, 1)">)
{
    </span><span style="color: rgba(128, 0, 128, 1)">$room_file</span> = './chat_data/' . <span style="color: rgba(128, 0, 128, 1)">$room</span> . '.txt'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(128, 0, 128, 1)">$msg_list</span> =<span style="color: rgba(0, 0, 0, 1)"> [];

    </span><span style="color: rgba(128, 0, 128, 1)">$room_data</span> = json_decode(<span style="color: rgba(0, 128, 128, 1)">file_get_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$room_file</span>), <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(128, 0, 128, 1)">$list</span> = <span style="color: rgba(128, 0, 128, 1)">$room_data</span>['list'<span style="color: rgba(0, 0, 0, 1)">];

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 清楚1分钟前消息</span>
    <span style="color: rgba(128, 0, 128, 1)">$cur_list</span> =<span style="color: rgba(0, 0, 0, 1)"> [];
    </span><span style="color: rgba(128, 0, 128, 1)">$del_time</span> = <span style="color: rgba(0, 128, 128, 1)">date</span>('Y-m-d H:i:s', <span style="color: rgba(0, 128, 128, 1)">time</span>() - 60<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(128, 0, 128, 1)">$list</span> <span style="color: rgba(0, 0, 255, 1)">as</span> <span style="color: rgba(128, 0, 128, 1)">$r</span><span style="color: rgba(0, 0, 0, 1)">)
    {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$r</span>['time'] &gt; <span style="color: rgba(128, 0, 128, 1)">$del_time</span><span style="color: rgba(0, 0, 0, 1)">)
      {
            </span><span style="color: rgba(128, 0, 128, 1)">$cur_list</span>[] = <span style="color: rgba(128, 0, 128, 1)">$r</span><span style="color: rgba(0, 0, 0, 1)">;
      }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 128, 128, 1)">count</span>(<span style="color: rgba(128, 0, 128, 1)">$cur_list</span>) != <span style="color: rgba(0, 128, 128, 1)">count</span>(<span style="color: rgba(128, 0, 128, 1)">$list</span>) &amp;&amp; <span style="color: rgba(0, 128, 128, 1)">count</span>(<span style="color: rgba(128, 0, 128, 1)">$list</span>) &gt; 0<span style="color: rgba(0, 0, 0, 1)">)
    {
      </span><span style="color: rgba(128, 0, 128, 1)">$room_data</span>['list'] = <span style="color: rgba(128, 0, 128, 1)">$cur_list</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 128, 128, 1)">file_put_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$room_file</span>, json_encode(<span style="color: rgba(128, 0, 128, 1)">$room_data</span><span style="color: rgba(0, 0, 0, 1)">));
    }

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查找最新消息</span>
    <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(128, 0, 128, 1)">$list</span> <span style="color: rgba(0, 0, 255, 1)">as</span> <span style="color: rgba(128, 0, 128, 1)">$r</span><span style="color: rgba(0, 0, 0, 1)">)
    {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$r</span>['id'] &gt; <span style="color: rgba(128, 0, 128, 1)">$last_id</span><span style="color: rgba(0, 0, 0, 1)">)
      {
            </span><span style="color: rgba(128, 0, 128, 1)">$msg_list</span>[] = <span style="color: rgba(128, 0, 128, 1)">$r</span><span style="color: rgba(0, 0, 0, 1)">;
      }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$msg_list</span><span style="color: rgba(0, 0, 0, 1)">;
}

</span><span style="color: rgba(128, 0, 128, 1)">$room_file</span> = './chat_data/' . <span style="color: rgba(128, 0, 128, 1)">$room</span> . '.txt'<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">switch</span> (<span style="color: rgba(128, 0, 128, 1)">$type</span><span style="color: rgba(0, 0, 0, 1)">)
{
    </span><span style="color: rgba(0, 0, 255, 1)">case</span> 'enter':   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 进入房间</span>
      <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">case</span> 'get':   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取消息</span>
      <span style="color: rgba(128, 0, 128, 1)">$last_id</span> = <span style="color: rgba(128, 0, 128, 1)">$_REQUEST</span>['last_id'<span style="color: rgba(0, 0, 0, 1)">];
      </span><span style="color: rgba(128, 0, 128, 1)">$msg_list</span> =<span style="color: rgba(0, 0, 0, 1)"> [];

      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 128, 128, 1)">strpos</span>(<span style="color: rgba(128, 0, 128, 1)">$_SERVER</span>['SERVER_SOFTWARE'], 'nginx') !== <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)
      {
            </span><span style="color: rgba(128, 0, 128, 1)">$msg_list</span> = getMsg(<span style="color: rgba(128, 0, 128, 1)">$room</span>, <span style="color: rgba(128, 0, 128, 1)">$last_id</span><span style="color: rgba(0, 0, 0, 1)">);
      }
      </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
      {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> nginx 使用sleep将会把整个网站卡死</span>
            <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(128, 0, 128, 1)">$i</span>=0; <span style="color: rgba(128, 0, 128, 1)">$i</span>&lt;20; <span style="color: rgba(128, 0, 128, 1)">$i</span>++<span style="color: rgba(0, 0, 0, 1)">)
            {
                </span><span style="color: rgba(128, 0, 128, 1)">$msg_list</span> = getMsg(<span style="color: rgba(128, 0, 128, 1)">$room</span>, <span style="color: rgba(128, 0, 128, 1)">$last_id</span><span style="color: rgba(0, 0, 0, 1)">);
               
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 255, 1)">empty</span>(<span style="color: rgba(128, 0, 128, 1)">$msg_list</span><span style="color: rgba(0, 0, 0, 1)">))
                {
                  </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
                }
   
                </span><span style="color: rgba(0, 128, 128, 1)">usleep</span>(500000<span style="color: rgba(0, 0, 0, 1)">);
            }
      }

      </span><span style="color: rgba(0, 0, 255, 1)">echo</span> json_encode(['result' =&gt; 'ok', 'list' =&gt; <span style="color: rgba(128, 0, 128, 1)">$msg_list</span><span style="color: rgba(0, 0, 0, 1)">]);

      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">case</span> 'send':    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 发送消息</span>
      <span style="color: rgba(128, 0, 128, 1)">$item</span> =<span style="color: rgba(0, 0, 0, 1)"> [
            </span>'id' =&gt; <span style="color: rgba(0, 128, 128, 1)">round</span>(<span style="color: rgba(0, 128, 128, 1)">microtime</span>(<span style="color: rgba(0, 0, 255, 1)">true</span>) * 1000),
            'user' =&gt; <span style="color: rgba(128, 0, 128, 1)">$_REQUEST</span>['user'],
            'content' =&gt; <span style="color: rgba(128, 0, 128, 1)">$_REQUEST</span>['content'],
            'time' =&gt; <span style="color: rgba(0, 128, 128, 1)">date</span>('Y-m-d H:i:s'),<span style="color: rgba(0, 0, 0, 1)">
      ];
      </span><span style="color: rgba(128, 0, 128, 1)">$room_data</span> = json_decode(<span style="color: rgba(0, 128, 128, 1)">file_get_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$room_file</span>), <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(128, 0, 128, 1)">$room_data</span>['list'][] = <span style="color: rgba(128, 0, 128, 1)">$item</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 128, 128, 1)">file_put_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$room_file</span>, json_encode(<span style="color: rgba(128, 0, 128, 1)">$room_data</span><span style="color: rgba(0, 0, 0, 1)">));
      </span><span style="color: rgba(0, 0, 255, 1)">echo</span> json_encode(['result' =&gt; 'ok'<span style="color: rgba(0, 0, 0, 1)">]);
      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">case</span> 'new':   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 新建房间</span>
      <span style="color: rgba(0, 128, 128, 1)">mt_srand</span><span style="color: rgba(0, 0, 0, 1)">();
      </span><span style="color: rgba(128, 0, 128, 1)">$room</span> = <span style="color: rgba(0, 128, 128, 1)">strtoupper</span>(<span style="color: rgba(0, 128, 128, 1)">md5</span>(<span style="color: rgba(0, 128, 128, 1)">uniqid</span>(<span style="color: rgba(0, 128, 128, 1)">mt_rand</span>(), <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)));
      </span><span style="color: rgba(128, 0, 128, 1)">$room</span> = <span style="color: rgba(0, 128, 128, 1)">substr</span>(<span style="color: rgba(128, 0, 128, 1)">$room</span>, 0, 10<span style="color: rgba(0, 0, 0, 1)">);
      newRoom(</span><span style="color: rgba(128, 0, 128, 1)">$room</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 128, 128, 1)">header</span>('Location:chat.php?room=' . <span style="color: rgba(128, 0, 128, 1)">$room</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">default</span>:
      <span style="color: rgba(0, 0, 255, 1)">echo</span> 'ERROR:no type!'<span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}

</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$type</span> != 'enter'<span style="color: rgba(0, 0, 0, 1)">)
{
    </span><span style="color: rgba(0, 0, 255, 1)">exit</span><span style="color: rgba(0, 0, 0, 1)">;
}

</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 128, 128, 1)">file_exists</span>(<span style="color: rgba(128, 0, 128, 1)">$room_file</span><span style="color: rgba(0, 0, 0, 1)">))
{
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$room</span> == 'default'<span style="color: rgba(0, 0, 0, 1)">)
    {
      newRoom(</span><span style="color: rgba(128, 0, 128, 1)">$room</span><span style="color: rgba(0, 0, 0, 1)">);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
    {
      </span><span style="color: rgba(0, 0, 255, 1)">echo</span> 'ERROR:room not exists!'<span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">exit</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}

</span><span style="color: rgba(128, 0, 128, 1)">$room_data</span> = json_decode(<span style="color: rgba(0, 128, 128, 1)">file_get_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$room_file</span>), <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">unset</span>(<span style="color: rgba(128, 0, 128, 1)">$room_data</span>['list'<span style="color: rgba(0, 0, 0, 1)">]);

</span><span style="color: rgba(128, 0, 128, 1)">$user</span> = 'User' . <span style="color: rgba(0, 128, 128, 1)">str_pad</span>((<span style="color: rgba(0, 128, 128, 1)">time</span>() % 99 + 1), 2, '0',<span style="color: rgba(0, 0, 0, 1)"> STR_PAD_LEFT);

</span>?&gt;
&lt;!DOCTYPE html&gt;
&lt;html lang="zh-CN"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
&lt;meta name="renderer" content="webkit"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
&lt;title&gt;PHP 在线聊天&lt;/title&gt;

&lt;link href="https://lib.baomitu.com/normalize/latest/normalize.min.css" rel="stylesheet"&gt;
&lt;style&gt;
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> css style </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
body{
    padding</span>:0<span style="color: rgba(0, 0, 0, 1)"> 10px;
}
</span>.<span style="color: rgba(0, 0, 0, 1)">divMain{
    font</span>-size:<span style="color: rgba(0, 0, 0, 1)">14px;
    line</span>-height: 2<span style="color: rgba(0, 0, 0, 1)">;
}

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">divList span{</span>
    color:<span style="color: rgba(0, 0, 0, 1)">gray;
}

</span>&lt;/style&gt;

&lt;script src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
   
&lt;h1&gt;PHP 在线聊天&lt;/h1&gt;
&lt;div <span style="color: rgba(0, 0, 255, 1)">class</span>="divMain"&gt;
&lt;?php <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$room</span> != 'default'){?&gt;
&lt;div&gt;复制网页链接发给朋友一起聊天!&lt;/div&gt;
&lt;?php } ?&gt;<span style="color: rgba(0, 0, 0, 1)">
昵称:</span>&lt;input id="txtUser" type="text" maxlength="50" value="&lt;?=<span style="color: rgba(128, 0, 128, 1)">$user</span>?&gt;" /&gt;
&lt;button onclick="$('#divList').html('');"&gt;清空&lt;/button&gt;
&amp;<span style="color: rgba(0, 0, 0, 1)">nbsp;
</span>&lt;a href="chat.php?type=new"&gt;新房间&lt;/a&gt;
&lt;br&gt;<span style="color: rgba(0, 0, 0, 1)">
内容:</span>&lt;input id="txtContent" type="text" value="" maxlength="100" style="width: 300px;" /&gt;
&lt;button onclick="sendMsg();"&gt;发送&lt;/button&gt;

&lt;hr&gt;
&lt;div id="divList"&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;!--使用worker获取消息数据,注意ngnix会阻塞整个进程--&gt;
&lt;script id="worker" type="app/worker"&gt;
    <span style="color: rgba(0, 0, 255, 1)">var</span> room = '&lt;?=$room_data['name']?&gt;'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> isBusy = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> lastId = -1<span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 0, 255, 1)">var</span> urlBase = ''<span style="color: rgba(0, 0, 0, 1)">;
    addEventListener(</span>'message', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (evt) {
      urlBase </span>= evt.<span style="color: rgba(0, 0, 0, 1)">data;
    }</span>, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
    setInterval(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (isBusy) <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
      isBusy </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;

      let url </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> URL( 'chat.php?type=get&amp;room=' + room + '&amp;last_id=' + lastId,<span style="color: rgba(0, 0, 0, 1)"> urlBase );
      fetch(url)
      </span>.then(res=&gt;res.<span style="color: rgba(0, 0, 0, 1)">json())
      </span>.then(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(res){
            isBusy </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (res.<span style="color: rgba(0, 0, 255, 1)">list</span>.length &gt; 0<span style="color: rgba(0, 0, 0, 1)">)
            {
                lastId </span>= res.<span style="color: rgba(0, 0, 255, 1)">list</span>.<span style="color: rgba(0, 0, 0, 1)">id;
            }
            self</span>.<span style="color: rgba(0, 0, 0, 1)">postMessage(res);
      })
      </span>.<span style="color: rgba(0, 0, 255, 1)">catch</span>(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
            isBusy </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
      });
    }</span>, 1000<span style="color: rgba(0, 0, 0, 1)">);
</span>&lt;/script&gt;
&lt;script&gt;
    <span style="color: rgba(0, 0, 255, 1)">var</span> blob = <span style="color: rgba(0, 0, 255, 1)">new</span> Blob();
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> url = window.URL.<span style="color: rgba(0, 0, 0, 1)">createObjectURL(blob);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> worker = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Worker(url);

    worker</span>.onmessage = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (e) {
      let res </span>= e.<span style="color: rgba(0, 0, 0, 1)">data;
      let html </span>= ''<span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">for</span> (let k in res.<span style="color: rgba(0, 0, 255, 1)">list</span><span style="color: rgba(0, 0, 0, 1)">)
      {
            let r </span>= res.<span style="color: rgba(0, 0, 255, 1)">list</span><span style="color: rgba(0, 0, 0, 1)">;
            html </span>= '&lt;div&gt;&lt;span&gt;' + r.<span style="color: rgba(0, 128, 128, 1)">time</span> + '&lt;/span&gt; &lt;b&gt;' + r.user + ':&lt;/b&gt; &amp;nbsp; ' + decodeContent(r.content) + '&lt;/div&gt;' +<span style="color: rgba(0, 0, 0, 1)"> html;
      }

      $(</span>'#divList').<span style="color: rgba(0, 0, 0, 1)">prepend(html);
    };

    worker</span>.postMessage(document.<span style="color: rgba(0, 0, 0, 1)">baseURI);
</span>&lt;/script&gt;

&lt;script&gt;
<span style="color: rgba(0, 0, 255, 1)">var</span> room = &lt;?=json_encode(<span style="color: rgba(128, 0, 128, 1)">$room_data</span>)?&gt;<span style="color: rgba(0, 0, 0, 1)">;
room[</span>'decode'] =<span style="color: rgba(0, 0, 0, 1)"> {};
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (let k in room.<span style="color: rgba(0, 0, 0, 1)">encode)
{
    room[</span>'decode']] =<span style="color: rgba(0, 0, 0, 1)"> k;
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 发送消息</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> lastSendTime = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sendMsg()
{
    let user </span>= $('#txtUser').val().<span style="color: rgba(0, 128, 128, 1)">trim</span><span style="color: rgba(0, 0, 0, 1)">();
    let content </span>= $('#txtContent').val().<span style="color: rgba(0, 128, 128, 1)">trim</span><span style="color: rgba(0, 0, 0, 1)">();

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (content == ''<span style="color: rgba(0, 0, 0, 1)">)
    {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (user == ''<span style="color: rgba(0, 0, 0, 1)">)
    {
      alert(</span>'昵称不能为空'<span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }

    window</span>.localStorage.setItem('r_' + room.name,<span style="color: rgba(0, 0, 0, 1)"> user);
   
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 限制0.5秒内仅允许发送1条消息</span>
    let curTime = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 128, 128, 1)">Date</span>().<span style="color: rgba(0, 0, 0, 1)">getTime();
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (curTime - lastSendTime &lt; 500<span style="color: rgba(0, 0, 0, 1)">)
    {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    lastSendTime </span>=<span style="color: rgba(0, 0, 0, 1)"> curTime;

    $</span>.<span style="color: rgba(0, 0, 0, 1)">ajax({
      url</span>:'chat.php?type=send',<span style="color: rgba(0, 0, 0, 1)">
      data</span>:{room:room.name, user:user, content:encodeContent(content)},<span style="color: rgba(0, 0, 0, 1)">
      type</span>:'POST',<span style="color: rgba(0, 0, 0, 1)">
      dataType</span>:'json',<span style="color: rgba(0, 0, 0, 1)">
      success</span>:<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
            $(</span>'#txtContent').val(''<span style="color: rgba(0, 0, 0, 1)">);
            $(</span>'#txtContent').<span style="color: rgba(0, 0, 0, 1)">focus();
      }</span>,<span style="color: rgba(0, 0, 0, 1)">
    });
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 消息加密</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> encodeContent(content)
{
    content </span>=<span style="color: rgba(0, 0, 0, 1)"> encodeURIComponent(content);
    content </span>= window.<span style="color: rgba(0, 0, 0, 1)">btoa(content);

    let str </span>= ''<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (let i=0; i&lt;content.length; i++<span style="color: rgba(0, 0, 0, 1)">)
    {
      str </span>+= <span style="color: rgba(0, 0, 255, 1)">String</span>.fromCharCode(room.encode);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> str;
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 消息解密</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> decodeContent(content)
{
    let str </span>= ''<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (let i=0; i&lt;content.length; i++<span style="color: rgba(0, 0, 0, 1)">)
    {
      str </span>+= <span style="color: rgba(0, 0, 255, 1)">String</span>.fromCharCode(room.decode);
    }

    str </span>= window.<span style="color: rgba(0, 0, 0, 1)">atob(str);
    str </span>=<span style="color: rgba(0, 0, 0, 1)"> decodeURIComponent(str);

    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> str;
}

$(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
    let userName </span>= window.localStorage.getItem('r_' + room.<span style="color: rgba(0, 0, 0, 1)">name);
    </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (userName)
    {
      $(</span>'#txtUser').<span style="color: rgba(0, 0, 0, 1)">val(userName);
    }

    $(</span>'#txtContent').keydown(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(e){
      </span><span style="color: rgba(0, 0, 255, 1)">if</span>(e.keyCode==13<span style="color: rgba(0, 0, 0, 1)">){
            event</span>.<span style="color: rgba(0, 0, 0, 1)">preventDefault();
            sendMsg();
      }
    });

    $(</span>'#txtContent').val('😀 我来了!'<span style="color: rgba(0, 0, 0, 1)">);
    sendMsg();
});

</span>&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    <hr>
<b>
欢迎转载,转载请注明:转载自[
http://www.cnblogs.com/zjfree/
]</b><br><br>
来源:https://www.cnblogs.com/zjfree/p/15352443.html
頁: [1]
查看完整版本: PHP 单页面在线聊天