这篇文章有为解决的问题。慎用。
问题会在代码处标注,未解决。
swoole不能在window下使用。我这里使用的是线上服务器linux系统。
这是服务端代码。
没有注释的代码为源码但是又bug。如果不介意代码些许bug仅供自己测试使用可以根据注释使用。
$clientFds = [];
# 创建websocket服务
$server = new swoole_websocket_server("0.0.0.0", 9501);
# 握手成功 触发回调函数
$server->on('open', function (swoole_websocket_server $server, $request) use (&$clientFds) {
# echo "server: handshake success with fd{$request->fd}\n";
# 将所有客户端连接标识,握手成功后保存到数组中
//数据无法追加,每次数据连接时,数组状态都为空。
//但是fd数据会+1.为int类型 列:1,2,3,4;
$clientFds[] = $request->fd;
});
# 收到消息 触发回调函数
$server->on('message', function (swoole_websocket_server $server, $frame) use (&$clientFds) {
# echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
# $server->push($frame->fd, "this is server");
# 当有用户发送信息,发送广播通知所有用户
//数据写死时可以发送数据。
// $server->push(1, $frame->data);
// $server->push(2, $frame->data);
//声明这段代码有问题。因为上方数据中当第二条数据加入数组时,数组为空,所以只能给发送信息的用户同步数据。
// for($i=0;$i<=$clientFds;$i++){
// $server->push($i, $frame->data);
// }
foreach ($clientFds as $fd) {
$server->push($fd, $frame->data);
}
});
# 关闭连接 触发回调函数
$server->on('close', function ($ser, $fd) use (&$clientFds) {
# echo "client {$fd} closed\n";
# 关闭会话 销毁标识fd
# 根据value 去数组中找对应的key
$res = array_search($fd, $clientFds, true);
unset($clientFds[$res]);
});
# 启动websocket服务
$server->start();
客户端代码,只展示重要部分。细节需要自己搞定。
<script type="text/javascript">
var name =prompt("请输入您的昵称","匿名者"); //弹出input框
// 打开一个 web socket
var ws = new WebSocket("ws://106.14.223.21:9501");
//连接成功后触发
ws.onopen = function() {
console.log("连接成功");
};
//收到消息 触发回调
ws.onmessage = function (evt) {
var data = evt.data;
console.log("收到socket服务消息,内容:" + data);
$('#main').append("<p>" + data + "</p>");
};
//发送数据。
function send() {
var data = document.getElementById('textarea').value;
ws.send(name+ ":"+ data);
}
//连接关闭后。
ws.onclose = function() {
// 关闭 websocket
console.log("连接已关闭...");
};
</script>
因为fd为自增长数据,所以我使用for循环进行向用户发送数据。问题在与当用户断开连接的时候循环数据还是会向用户发送数据。我也不太清楚fd的增长模式。所以未解决。