前端js后端nginx+php+workerman实现websocket通信

workerman是纯PHP开发的开源PHP 应用容器,可以通过composer安装,目前因为要用到客户端与服务器实时通信,故使用了workerman中的websocket模块功能

服务器端:

1.建一个目录,创建start.php文件,文件名随意

2.composer安装workerman

composer require workerman/workerman

3.根据worker示例编写代码

简单的开发示例-workerman手册

<?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.注意自己实现一个心跳,以免长时间没有收发数据导致连接断开

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值