失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 微信小程序之swoole/WebSocket创建聊天室(php)

微信小程序之swoole/WebSocket创建聊天室(php)

时间:2019-11-12 16:03:17

相关推荐

微信小程序之swoole/WebSocket创建聊天室(php)

一、php安装扩展组件Swoole

参考连接

二、配置linux服务器

在站点的配置文件中#SSL-END下面添加代码

location /wss/ {#通过配置端口指向部署websocker的项目proxy_pass http://127.0.0.1:9205/;proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-real-ip $remote_addr;proxy_set_header X-Forwarded-For $remote_addr;}

注意:

1、端口号不能与同服务器的wss一样

2、开放对应的端口(9205)

三、配置微信小程序socket合法域名

注意:后面不需要加端口 ,在站点的配置文件中已经做了定向

四、服务器命令执行wss.php文件(以下命令请在wss.php文件对应的目录执行)

测试启动:php wss.php

设置常驻:nohup php -f wss.php

执行完成后,在对应的文件目录下面会生成一个nohup.out记录文件(不要删除这个文件)

查看进程:netstat -ntlp

结束进程:kill 进程编号

注意:上线一定要执行常驻命令,不执行会报错。因为终端关闭后就无法建立连接。

终端:

nohup.out文件:

五、微信小程序创建连接

在小程序全局app.js初始化时执行创建连接

var util = require("pages/utils/util.js");var websocket = require("pages/utils/websocket.js");//app.jsApp({//全局变量globalData: {swook_url: "wss://*********/wssc/",//webSocketWebSocketSendMsgCallback: function () {},},/*** 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)*/onLaunch: function () {var that = this;//心跳设置var userInfo = wx.getStorageSync('userInfo') || {};if (userInfo.id) { //必须在登录状态下才可以连接that.linkWebsocket(userInfo);}},/*** 当小程序从前台进入后台,会触发 onHide*/onHide: function () {var that = this;},/*** 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息*/onError: function (msg) {},//开启WebSocketlinkWebsocket: function (userInfo) {var that = this;wx.connectSocket({url: that.globalData.swook_url,success(res) {console.log('连接成功~')wx.onSocketOpen(() => {console.log('WebSocket连接打开');//第一次创建连接成功时获取分配的$fd存入数据库,绑定用户wx.sendSocketMessage({data: JSON.stringify({pages: 'A_member',act: 'initSocket',member_id: userInfo.id,content: 'initSocket',})})//数据返回处理wx.onSocketMessage((res) => {var objData = JSON.parse(res.data);if (objData.code == "600") {//处理数据that.globalData.WebSocketSendMsgCallback(objData);}})//连接成功打开,拉起心跳检测websocket.linkWebsocket_xin(40000, true);})},});wx.onSocketError(function (res) {console.log('打开失败~,请联系管理员');});}})

pages\utils\websocket.js

注意:发送信息时也算是一次心跳,所以在发送信息之前把当前的心跳关闭,发送成功之后再以发送成功时的时间再次建立心跳连接。

例如:我在10:00:00发送的心跳连接,下次的心跳应该是10:00:40。但是我在10:00:10时发送了一条信息,那么下次的心跳连接时间应该是10:00:50

//心跳重连检测function linkWebsocket_xin(lian_time, mag) {if (mag == true) {var dingshi_title = '';dingshi_title = setInterval(function () {console.log("当前心跳已重新连接");//循环执行代码wx.sendSocketMessage({data: JSON.stringify({pages: 'A_member',act: 'ping',}),fail(res) {// console.log(res)}});}, lian_time) //循环时间,注意不要超过1分钟 wx.setStorageSync('dingshi_title', dingshi_title);} else {var dingshi_title = wx.getStorageSync('dingshi_title') ? wx.getStorageSync('dingshi_title') : '';//关闭定时器clearInterval(dingshi_title);console.log("当前心跳已关闭");}}//发送消息function send(msg) {//关闭定时器linkWebsocket_xin(40000, false);wx.sendSocketMessage({data: msg,success(res) {//重置定时器时间linkWebsocket_xin(40000, true);},fail(res) {// console.log(res)}});}module.exports = {send: send,linkWebsocket_xin: linkWebsocket_xin,}

六、发送消息,推送原理

例如在一个聊天室中存在5个人,那么这个聊天室会绑定这5个人的会员ID,利用会员ID在获取创建swook连接时分配的$fd,在分别进行通知。通知时需验证当前的$fd是否有效。

那么通知内容应该是什么呢?

我做的是,发送消息成功存入数据库后对小程序进行返回时,进行通知

例如:

//注意引入websocket.js//内容进程提交websocket.send(JSON.stringify({pages: 'A_member',act: 'add',detailId: that.data.detailId,//当前聊天室IDmessage: data.fan_arr,//发送的内容}),);

七、wss.php文件

面向过程和面向对象的写法官方给了哈<<点击进入

<?phpheader("Content-Type: application/json; charset=utf-8");include 'inc_serve.php';class WebsocketTest {public $server;public function __construct() {$this->server = new Swoole\WebSocket\Server("0.0.0.0", 9205);$this->server->on('open', function (swoole_websocket_server $server, $request) {//用于指定连接成功后的回调函数echo date("Y-m-d H:i:s") . ":用户 fd{$request->fd} 成功链接\n";});$this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {//用于指定收到服务器数据后的回调函数// echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";//$server->push($frame->fd, "this is server");////引用$conn = _conn();$infoArray = array();$infoArray["code"] = 0;$infoArray["msg"] = "REQUEST FAILED";$webSocket_id = $frame->fd;$webSocket_data = $frame->data;$webSocket_data = htmlspecialchars_decode($webSocket_data);$webSocket_data = $webSocket_data ? json_decode($webSocket_data, true) : array();if(!is_array($webSocket_data)){$webSocket_data = array();}$pages = $webSocket_data["pages"];$act = $webSocket_data["act"];$detailId = (int)$webSocket_data["detailId"];$member_id = (int)$webSocket_data["member_id"];$message = $webSocket_data["message"];//logecho date("Y-m-d H:i:s") . ":用户 fd{$frame->fd} 发送消息 {$pages},{$act},{$detailId}\n";if($pages == "A_member"){if($act=="initSocket"){//首次握手用户绑定_wss_member_fid($this->server, $conn, $webSocket_id, $member_id);$infoArray["code"] = 200;$infoArray["msg"] = "initSocket success";}elseif($act=='add'){//发送消息返回//$infoArray["code"] = 200;//$infoArray["msg"] = "OK";include ("A_chat.php");}elseif($act=='ping'){//心跳连接$infoArray["code"] = 666;$infoArray["msg"] = "OK_xin";$infoArray["content"] = "pong";}}//发送$json = json_encode($infoArray, true);$server->push($webSocket_id, $json);});$this->server->on('close', function ($ser, $webSocket_id) {//用于指定连接关闭后的回调函数//echo "client {$fd} closed\n";//引用$infoArray["code"] = 200;$infoArray["msg"] = "initSocket success";$infoArray["webSocket_id"] = $webSocket_id;$conn = _conn();//获取if($webSocket_id){$sqlrm = "select * from a_member where webSocket_id='".$webSocket_id."' ";$resultrm = mysqli_query($conn,$sqlrm); $rm = mysqli_fetch_array($resultrm);//logecho date("Y-m-d H:i:s") . ":用户 fd{$webSocket_id} 关闭链接\n";//清除状态$sqlEdit = "update a_member set webSocket_id=0 where webSocket_id={$rm["webSocket_id"]}";$resultEdit = mysqli_query($conn,$sqlEdit);}});$this->server->on('request', function ($request, $response) {// 接收http请求echo "request\n";echo json_encode($request)."\n";echo json_encode($response)."\n";echo $request->get['message']."\n";// // 接收http请求从get获取message参数的值,给用户推送// // $this->server->connections 遍历所有websocket连接用户的fd,给所有用户推送// foreach ($this->server->connections as $fd) {//// 需要先判断是否是正确的websocket连接,否则有可能会push失败//if ($this->server->isEstablished($fd)) {//$this->server->push($fd, $request->get['message']);//}// }});$this->server->start();}}new WebsocketTest();?>

八、发送消息返回

WebSocketSendMsgCallback,这个是实时返回。

wx.onSocketMessage((res) => {var objData = JSON.parse(res.data);if (objData.code == "600") {//处理数据that.globalData.WebSocketSendMsgCallback(objData);}})

接收数据:

app.globalData.WebSocketSendMsgCallback = function (data) {if (data.act == "chat_room_list" && data.pages == "A_chat") {var subjects = that.data.subjects;var message = data.message;if (data.member_id == userInfo.id) {message[0].admin = 1;} else {message[0].admin = 2;}subjects = subjects.concat(message);that.setData({subjects,})}}

九、日志查看

另外还有就是如果服务器重启了,需要服务器再次执行wss.php文件

当会员退出登录时,那么当前的连接应该断了wx.closeSocket();

wss.php文件中有监听断开的处理,应该是把绑定会员的fd清除。

如果会员登录时,那么应该在次建立连接

如果觉得《微信小程序之swoole/WebSocket创建聊天室(php)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。