目录
零.在thinkphp5环境下搭建gatewayWork环境
零.在thinkphp5环境下搭建gatewayWork环境
1.在官网上下载文件包,传送门https://www.workerman.net/download,根据自己机器的环境下载对应的gatewayWork即可
2.下载完成后解压到你TP5项目的vendor目录下即可,如图
3.点击start_for_win.bat文件即可成功启动你的webSocked服务器,如果你是linux的系统运行一下start.php文件即可
dos界面如下即成功运行
一.在视图文件建立与webSocked服务器的连接
因为是我的webSocked服务器放在本地,所以地址就是127.0.0.1,到时候如果有需要,将地址改为你webSocked服务器的地址就行
//连接websocket服务器
let ws = new WebSocket("ws://127.0.0.1:8282");
坑:
有的浏览器可能默认没有打开webSocked,如果按照上面的代码你不能连接成功的话,可以根据的浏览器去设置一下即可
二.websocked服务器向客户端发送消息
注意服务器所有的代码都在event文件内编写,并且改变该文件内容和需要重启webSocked服务器
该文件物理地址
D:\phpStudy2018\PHPTutorial\WWW\Qbling_mall\vendor\GatewayWorker\Applications\YourApp
在websocked服务器上有三种发送的方式
1.服务器向所有客户端发送
Gateway::sendToAll($client_obj);
使用这行代码,服务器就会向所有的与服务器长连接的客户端发送消息,其中$client_obj类型为字符串由我们自定义,
我为了前后端交互方便,就将需要发送的消息的内容转化为json对象
2.服务器向某一客户端发送
//当客户端连接的时候,要求客户发送uid进行绑定
Gateway::sendToClient($client_id,json_encode([
'type'=>'init',
'client_id' => $client_id
]));
使用这个方法,以后服务器会向某个client_id发送消息,第一个参数为我们指定的client_id,第二个就是我们想要发送的字符串信息
在这里我们谈谈,client_id与uid,这两个就像数据库里的主键一样,
一个uid对应多个clientid,一个client_id只能对应一个uid
举个例子,clientid就像你上学时的学号一样,uid就像你的身份证号
你小学,中学,和大学的学号肯定不一样吧,但是他们都对应你这个人
当我们使用长连接时,页面的每一次刷新,都会与服务器都会重新给我们这个链接的客户端生成一个新的clientid
就相当于你通过了高考,从高中到了大学,那么你会重新获得一个大学的学号,你的高中学号也就失去了意义,
但是,如果服务器就想专门给你发送一个消息,怎么办呢,如果服务器是给你的client_id发送消息,是很危险的
因为你这个客户端可能中间刷新了几次,你的clientid就会像你的学号一样发生了变化,所以可能会收不到信息
这时候uid就出场了,它相当于你的身份证号,
服务器直接给你的身份证号发送消息,它不管你现在处于什么阶段,clientid会不会改变,但是它知道你的uid是肯定不会变得,
所以服务器就确保了这个信息客户端一定能收到(客户端在线时)
3.服务器向某一uid发送(可能对应某几个客户端)
上面写了对某一client_id发送,那么就肯定有对某一uid发送啦,这里参数基本与上面一致,就是clientid换成了uid
Gateway::sendToUid($client_obj->from_uid,json_encode([
"type"=>"server_msg",
"data"=>'绑定成功!'
]));
三.服务器接受客户端发送的消息
先简单介绍下,服务器端的三个回调函数
1.onConnect
/**
* 当客户端连接时触发
* 如果业务不需此回调可以删除onConnect
*
* @param int $client_id 连接id
*/
public static function onConnect($client_id)
{
//code....
}
2.onMessage
/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $message){
//code..
}
3.onClose
/**
* 当用户断开连接时触发
* @param int $client_id 连接id
*/
public static function onClose($client_id)
{
//code...
}
就这么简单的三个函数,
一个客户端链接上服务器的时候会触发,onConnect函数,然后一直连着,
什么时候觉得无聊了,给服务器发个消息,这时候就会触发onMesssage函数
,当客户端觉得没意识,决定下线时,会触发onClose
其中我们基本上绝大多数的业务处理都放在onMessage函数内,在这个函数内我们接受客户端给我们发送的信息
举个栗子
/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $message)
{
//获取客户端发送的json
$client_obj = json_decode($message);
//判断用户发送的信息的类型
switch ($client_obj->type){
//将client与客户端的uid绑定
case "bind":
Gateway::bindUid($client_id,$client_obj->from_uid);
Gateway::sendToUid($client_obj->from_uid,json_encode([
"type"=>"server_msg",
"data"=>'绑定成功!'
]));
break;
//code.............
//判断某个用户是否在线
case "is_online":
$status = Gateway::isUidOnline($client_obj->to_uid);
$data = [
"type" => "is_online",
"status" => $status,
];
//向发送者返回接受者是否在线的消息
Gateway::sendToUid($client_obj->from_uid,json_encode($data));
break;
}
}
根据我们与事先定义好的内容,来进行对应的逻辑操作
四.客户端向websocked服务器发送消息
在客户端给服务器发送消息就简单了
ws.send(JSON.stringify(send_obj));
先根据我们定义的与服务器链接的对象中的send方法就完事了,
但是注意发送的消息也只能是字符串哦,
所以我为了方便数据的交互,将服务器与客户端所有交互的数据全部转成了json格式
五.客户端接受websocked服务器发送的消息
这个也很简单
ws.onmessage = function(e){
//code...
}
服务器给客户端发送消息时,会触发们定义的与服务器链接的对象中的onmessage方法
在这个方法里面我们去写相应的逻辑就欧克了