赞
踩
workerman是纯PHP开发的开源PHP 应用容器,可以通过composer安装,目前因为要用到客户端与服务器实时通信,故使用了workerman中的websocket模块功能
1.建一个目录,创建start.php文件,文件名随意
2.composer安装workerman
composer require workerman/workerman
3.根据worker示例编写代码
- <?php
- use Workerman\Worker;
- use Workerman\Connection\TcpConnection;
- use Workerman\Protocols\Http\Request;
- require_once __DIR__ . '/vendor/autoload.php';
-
- // 创建一个Worker监听2345端口,使用websocket协议通讯
- // 不要把websocket写成了tcp或者http
- $http_worker = new Worker("websocket://0.0.0.0:6789");
-
- // 启动4个进程对外提供服务
- $http_worker->count = 4;
-
- $http_worker->onConnect = function(TcpConnection $connection)
- {
- echo "connected:\n";
- //var_dump($connection);
- echo "new connection from ip " . $connection->getRemoteIp() . "\n";
- };
-
- // 接收到浏览器发送的数据时回复hello world给浏览器
- $http_worker->onMessage = function(TcpConnection $connection, $data)
- {
- echo "get message:\n";
- var_dump($data);
- //var_dump($request);
- // 向浏览器发送hello world
- // Connection::send(mixed $data [,$raw = false])
- // 第二个参数是raw,发送的数据只是第一个参数,不要搞错了
- // https://www.workerman.net/doc/workerman/tcp-connection/send.html
- $connection->send('hello world' . $data);
- };
-
- $http_worker->onClose = function(TcpConnection $connection)
- {
- echo "connection closed\n";
- };
-
- // 运行worker
- Worker::runAll();

4.配置nginx
workerman默认是可以直接监听端口的,但是因为开发环境、防火墙、安全、其他项目等因素,js直接连服务器ip+端口,连不上,所以采用了nginx代理转发,server模块中添加如下location
- location /websocket {
- proxy_pass http://127.0.0.1:6789;
- #js前端ws = new WebSocket('wss://www.example.com/websocket');
- #workerman里面$http_worker = new Worker("websocket://0.0.0.0:6789");
- #这里就是代理转发到本地的6789端口
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "Upgrade";
- proxy_set_header Host $host;
- }
1.编写js代码
- // 创建 WebSocket 对象并建立连接
- var ws = null;
-
- try{
- ws = new WebSocket('wss://www.haoqi100.com/websocket');
- }catch(e){
- console.log("new socket catch", e)
- }
- console.log("get websocket:", ws)
- console.log("init event:")
- // 打开连接时触发的事件
- ws.onopen = function(event) {
- console.log('WebSocket 已连接');
- // onopen里面send会断开连接,应该是因为打乱了握手顺序
- setTimeout(()=>{
- ws.send('i am ok')
- // 发送心跳,不然时间长了会断开
- heartBeat()
- }, 1)
- };
-
- // 接收到消息时触发的事件
- ws.onmessage = function(event) {
- console.log('接收到服务器的消息:', event.data);
- };
-
- // 发生错误时触发的事件
- ws.onerror = function(error) {
- console.error('WebSocket 错误:', error);
- };
-
- // 关闭连接时触发的事件
- ws.onclose = function(event) {
- console.log('WebSocket 已关闭', event);
- ws = null
- };
-
- function heartBeat(){
- var heartInterval = setInterval(()=>{
- if(ws){
- ws.send('ping')
- }else{
- clearInterval(heartInterval)
- console.log("heartBeat finish")
- }
- }, 10000)
- }

1.前端js里面ws.onopen不要马上send,可能会打乱握手顺序
2.服务端的send有两个参数,第二个可选参数不会当成数据发送,不要搞错了
3.注意自己实现一个心跳,以免长时间没有收发数据导致连接断开
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。