YII2+swoole实现聊天室
发布时间:2022-05-27编辑:windydeng浏览(6031)评论览(0)
本文讲解的是在YII2配合swoole的前提下实现的一对一聊天,swoole可在服务器自行安装,安装教程链接:https://blog.csdn.net/gaokcl/article/details/91357622,安装过程需要注意的点如下:
1.编译安装
./configure配置PHP的文件路径要配对,不然会安装出错 例如:--with=php-config = /usr/local/php/bin/php-config
2.配置扩展
这里需要注意的是,php.ini文件增加swoole扩展,必要时加上绝对路径
其次讲下YII2,我是用的高级版,有前后台之分,目前的聊天室也是主要给线上项目www.phpfire.online
开发增加功能,好了,该步入正题了:
先看下我目前实现了界面效果,主要有,切换用户聊天,发送信息,消息接受者可实时接收消息同步
好了,首先贴下我服务器的代码,在YII2中,一般脚本执行文件都是在./commands下面创建控制器,我这是属于高级版,所以是放在了./console/controller里面,swoole服务器也是得在命令行cli模式下运行,具体如何运行如下:
这里需要有一个注意项,你此时运行程序,当此次终端关闭将会断开连接,如果你不想被终端,那么需要使用特定的运行命令来让这个进程一直运行下去,我目前是选择了使用nohup,nohup命令是永久执行,忽略挂起信号。&是指在后台运行。所以我运行linux程序的命令变成了这样:mohup ./yii swoole-chat/run &
接下来贴下我的swoole核心代码代码:
public function actionRun(){
$this->serv = new \swoole_websocket_server("0.0.0.0", 8090);
$this->serv->set(array(
'worker_num' => 8,
'daemonize' => false,
'max_request' => 10000,
'dispatch_mode' => 2,
'debug_mode' => 1
));
$this->serv->on('Open', array($this, 'onOpen'));
$this->serv->on('Message', array($this, 'onMessage'));
$this->serv->on('Close', array($this, 'onClose'));
$this->serv->start();
}
这段代码需要注意点的就是socket的连接了,有些朋友会发现连接不上socket,反斜杠需要,我采用8090这个端口作为swoole监听端口,需要去你的服务器安全组开放,这个方法保证,连接监听关闭三个操作的正常。
前端代码websockt的连接代码如下:
<script> var socket = new WebSocket('ws://192.168.122.128:8090'); // 打开Socket 这里的IP和端口填写你自己的 socket.onopen = function(event) { console.log(event); }; socket.onmessage=function(event){ console.log(event); } function sendMessage(touser){ socket.send(msg); } </script>
上面一段代码就是websockt的最基本的连接监听关闭了,注意上面WebSocket里面的IP地址和端口号要填写正确,不然会连接不上,其次就是每次连接,都会在服务器onopen产生连接数据,此时可以推送到前端展示一些初始化信息。但此时注意,此次服务器onopen方法推送的数据都是在前端onmessage方法接受,我这里是一对一聊天,所以在建立连接的时候,就需要初始化双方的聊天记录,例如有两个用户a和b,必须把用户a的uid和用户带着参数传递到swoole后台onopen方法去接受,我此时连接的websockt是这样的:
new WebSocket('ws://192.168.122.128:8090?uid=' + send_id + '&to_id=' + this.to_id);
让后台接受用户a的uid和用户b的uid之后,执行db操作查询历史记录,然后通过swoole后台的push操作推送给用户,push注意事项,两个参数,第一个,fd,第二个,push的数据
$ws->push($request->fd, "hello, welcome\n");//例如这样
这里有几个需要注意的点,fd是什么?简单来说,每次用户建立起一个socket进程之后,都会给这个进程
分配一个fd作为当前连接的唯一标识,当断开连接重新连接,fd会变化。其次就是推送的数据,我们需要把
推送的数据转换为字符串形式推送到前端:
$this->serv->push($fd, json_encode($chatData));
诸如上面就是我其中推送的代码,前端用JSON.parse去接受,将字符串转换为json对象
说到fd,在构建数据库表的设计中,我们需要创建一个fd绑定表,一个聊天记录表,fd绑定表用来绑定
用户uid和fd设计如下截图:
好了,不多哔哔,我们就此走通了websockt的连接和初始化历史消息,接下来讲发送消息,
socket.send(JSON.stringify(pData)); //这个前端就是发送消息的方法,注意需要转化为字符串传递
swoole后台接受的话,会自动在onMessage方法里面触发接受,
onMessage($server, $frame)//前端推送的数据就在$frame指向的data里面,$frame还包含了此次socket的fd
在这里注意,我每次发送消息进入onMessage方法都要注意当前传递的fd和数据库uid绑定的fd是否一致,否则需要更新fd,这里经过数据过滤,把返回信息推送给用户a和b,此时需要推送给两个用户,那么需要推送两次,通过查询数据库的fd去推送,至于其它的具体操作就不多讲了,本文讲的是一些细节问题,和注意事项,具体要实现一个真正的聊天,还需要写很多的代码,如果你有思考过各种场合的处理,就会发现还有很多代码需要开发。下面附一下我的主要代码,一些YII2的操作就不贴了:
关键字词:YII2+swoole实现聊天室
暂无评论