最近学习workerman,做一个简单的聊天页面,开始在网上各种百度,后来越来越感觉官方文档才是我们的好朋友,传送门:
http://doc2.workerman.net/
1)按照官网上的例子我们会感觉workerman很简单,但是回头我们毕竟要将它和框架用在一起,tp文档给了我们介绍了怎么使用,然而愚笨的我看完之后更是一脸懵逼,回头再看文档:
1》我们会发现官方文档并没有将gatewayworker和tp融合在一起,而是独立的运行,那么我们为什么不这样做呐??
2)我们直接下载GatewayWorker框架,我的是windows系统,传送门:
https://www.workerman.net/download
3)接下来的是,把他放在哪,怎么用??其实我们可以直接把压缩包解压放在tp框架的任何位置,我就直接解压放在项目目录下:
4)GatewayWorker给了我们很好的封装,我们只需要关注一个文件:
5)由于我是简单的测试,所以我只是改动了两个方法
1》onConnect当用户连接时初始化,绑定uid
2》onMessage处理逻辑需求
6)接下来我从代码流程开始一步一步操作,主要涉及两个文件
1》Events.php(GatewayWorker业务控制类)
2》show.html(前端交互页面)
7)下面运行流程正式开始:
1》首先我们先设置连接类型和监听端口,打开:
GatewayWorker\GatewayWorker\Applications\YourApp\start_gateway.php
在这个文件中我们只需要修改一行代码:
①协议:我测试使用的是Websocket
②ip地址:这个建议使用0.0.0.0,我本地测试所以使用127.0.0.1
③端口:这个很重要
④文档中这三个写的很详细,再次建议看文档
2》直接双击这个解压文件夹下面的start_for_win.bat,如果你看到这个那么恭喜你,GatewayWorker可以正常使用了:
3》环境已经完成了,那么切入我们的主题业务逻辑,用户访问的是页面,那么我们就从页面开始:假设我们是在模拟两个人聊天,他们两个人的id为fromid和toid,首先我们在js中实例化一个对象
var ws = new WebSocket('ws://127.0.0.1:8282');
①因为我刚才启动的时候使用的是 Websocket协议,所以我这里实例化Websocket
②ip和端口号一定要和上文的配置相同
4》当我们实例化成功之后这次连接会触发Events.php中的onConnect方法,我们来看一下这个方法都能做什么:
①这个方法中有一个参数$client_id,这是系统给我们的一个id,但是每次刷新它都会变
②这时我们向客户端发送一个消息,设置数组中的类型为init,意义为初始化
5》当服务器发送类型为init的数据时,这时刚刚操作的客户端就会触发onmessage方法,因为一会会有很多的数组类型,所以我用switch:
①在接收数据的时候我们需要对数据做类型转换
②我在客户端也定义了init的数组类型在这个分支中我做两件事情,绑定我的fromid和查看和我聊天的那个人在不在
6》当客户端发送这两个消息的时候,同样会触发服务器的onMessage方法:
①我们可以看到这个方法有两个参数
$client_id系统给你分配的id
$message客户端传来的参数
②在方法中我们同样需要将客户端传来的参数进行类型转换
③在init中我们绑定uid,将我们的身份确定,没有向客户端发消息
④在status中我们判断聊天对象是否在线,并将结果返回刚刚连接的客户端
7》这时再次触发客户端的onmessage方法,我们继续用switch类型判断逻辑:
①因为你现在有可能和多人聊天,所以需要对你的聊天对象进行判断
②应对返回值判断用户是否在线
8》至此客户端和聊天对象的初始化就算完成了,你确定了自己的固定id,也知道了对面是否在线
9》现在在show.html中我们需要创建一个input框用来输入信息,和一个button按钮提交信息,这个html很简单,现在我们关注button点击时触发的点击事件:
var info = $('#say').val();
var data = '{"type":"say","fromid":"'+fromid+'","toid":"'+toid+'","content":"'+info+'"}';
ws.send(data);
①我们需要获取输入框中的消息我们可以对输入框中的信息做一下自己想要的过滤
②我们同在预设发送消息的type类型,这样在服务器中就可以做对应的逻辑判断
10》当我们发送完消息之后,同样会触发服务器中的onmessage方法,由于我们发送数据的type是say,所以我们应该在say分支下处理逻辑
case"say":
$res['type'] = "say";
$res['fromid'] = $data['fromid'];
$res['toid'] = $data['toid'];
$res['content'] = $data['content'];
Gateway::sendToUid($data['toid'],json_encode($res));
break;
①我们在处理对话分支的时候一定要分清fromid和toid
②这次我们将消息应该发送到聊天对象那,而不是返回到自己,所以sendToUid的对象应该是toid,刚开始做这个的时候很乱,需要我们冷静下来慢慢捋顺。
11》服务器发送完消息之后,这是再次出发客户端的onmessage方法,这时我们需要在type=say的分支接收逻辑:
if(message.fromid == toid) {
$('#message-container').append('<div class="center-left"><img src="{:env('FACE_PATH')}'+topic+'" class="center-pic-left"><span class="center-mess-left">'+replace_em(message.content)+'</span></div>').scrollTop(3000);
}
break;
①这时我们回到客户端,我们的身份不再是发件人,而是应该站在收件人的角度考虑
②这时你是发件人,发过来的消息的发件人应该是你现在正在聊天的收件人
③如果收到的消息的发件人是你正在聊天的对象,那么就将消息追加到聊天列表中
12》到此一个从开启服务器到客户端绑定uid,再到发件人发送消息最后到收件人接收消息的小逻辑就完成了,我这个简单的例子没有加上tp框架的数据交互,只是涉及一个getawayWorker服务器和两个客户端,一定要理解好fromid和toid的相互关系:
8)我自己做了一个简单的demo,可以去看看我做的小聊天页面