微信小程序WebSocket开发

QQ截图20180406191419.png


让我们来实现一个简单的微信小程序WebSocket。WebSocket是一种没有被规范化的网络协议,不过网络上又有文章说是2011年被国际化。不过不管怎么样它摆脱了Http的无状态特性。什么是无状态,我看文章的时候有句话好经典:“人生若只如初见”。这句话完美的诠释了无状态。而WebSocket可以建立一种双向通道,即客户端可以通过此通道(Tcp)与服务器相互沟通,而服务器也可以通过此通道(Tcp)实现与服务器的沟通。而不必等待客户端的请求后再沟通。


注意WebSocket是一种协议,所以你需要让你的服务器能够解析这个协议。由于是Tcp为底层的,所以解析这个协议主要是“握手”。由于我的后台采用PHP编写,所以主要讲一下PHP的WebSocket利用。这个搭建过程你可以参考:http://www.iwonmo.com/archives/1287.html


两点注意:1、使用php cli模式来运行你的WebSocket代码。2、new对象的时候要new swoole_websocket_server。


如果你看过搭建过程了的话,那么下面这段代码你并不陌生了。

$server = new swoole_websocket_server("0.0.0.0", 你的WebSocket端口);
$server->on('open', function (swoole_websocket_server $server, $request) {
    echo "server: handshake success with fd{$request->fd}\n";
});
$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");
});
$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closed\n";
});
$server->start();

这里要注意你的nginx的反射端口,如果这个不会配置的话,可以留言。我将我的配置文档发送给你。

要实现微信小程序访问wss你还需要在你的微信小程序后台也就是微信的网站页面添加你的wss地址。这里的地址你可以通过nginx来设置,不过要注意要有ssl证书,这个证书你可以在阿里云申请。然后你可以新建你的小程序了。


注意swoole官网的一段话。

onRequest回调

swoole_websocket_server 继承自 swoole_http_server

  • 设置了onRequest回调,websocket服务器也可以同时作为http服务器

  • 未设置onRequest回调,websocket服务器收到http请求后会返回http 400错误页面

  • 如果想通过接收http触发所有websocket的推送,需要注意作用域的问题,面向过程请使用globalswoole_websocket_server进行引用,面向对象可以把swoole_websocket_server设置成一个成员属性


所以说如果你访问网址后出现400错误,不要惊慌。因为你查看request你会发现你并没有实现它。如果实现了就不会出现400。而是空白。

<?php
$server = new swoole_websocket_server("0.0.0.0", 你的WebSocket端口);
//握手完毕后回调函数
$server->on('open', function (swoole_websocket_server $server, $request) {
        echo "server: handshake success with fd{$request->fd}\n";
        // $server->push($request->fd, "this is server");
    });
//有消息到达时的回调函数
$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, "客户端消息:receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n");
        $server->push($frame->fd, "my server\n");
    });
//关闭时的一个回调
$server->on('close', function ($ser, $fd) {
        echo "client {$fd} closed\n";
    });
//协议头
$server->on('request', function (swoole_http_request $request, swoole_http_response $response) {
        global $server;//调用外部的server
        // $server->connections 遍历所有websocket连接用户的fd,给所有用户推送
        foreach ($server->connections as $fd) {
            $server->push($fd, $request->get['message']);
        }
    });
$server->start();

上述代码是我服务器的一段代码。可以看到首先New了一个swoole对象。然后接管了几个回调。注意的是swoole的websocket向客户端发送数据采用的是push而不是send。在来看一下微信小程序的JavaScript代码。

wx.connectSocket({
      url: 'wss://xxxxxx.com'
    })
    wx.onSocketOpen(function (res) {
      console.log('WebSocket连接已打开!')
      wx.sendSocketMessage({
        data: "aa"
      })
    })
    wx.onSocketMessage(function (res) {
      console.log('收到服务器内容:' + res.data)
      wx.closeSocket()
    })
    wx.onSocketClose(function (res) {
      console.log('WebSocket 已关闭!')
    })
    wx.onSocketError(function (res) {
      console.log('WebSocket连接打开失败,请检查!')
    })

基本上都是官网的代码。代码里的方法可以参考微信小程序官网的API文档来查看。我这里主要是发送了一个文本数据给swoole框架,然后框架解析出我的数据类型与数据相关的一些信息。这个在swoole的官网API有解释。

onMessage

当服务器收到来自客户端的数据帧时会回调此函数。

function onMessage(swoole_server $server, swoole_websocket_frame $frame)
  • $frame 是swoole_websocket_frame对象,包含了客户端发来的数据帧信息

  • onMessage回调必须被设置,未设置服务器将无法启动

  • 客户端发送的ping帧不会触发onMessage,底层会自动回复pong

swoole_websocket_frame

共有4个属性,分别是

  • $frame->fd,客户端的socket id,使用$server->push推送数据时需要用到

  • $frame->data,数据内容,可以是文本内容也可以是二进制数据,可以通过opcode的值来判断

  • $frame->opcode,WebSocket的OpCode类型,可以参考WebSocket协议标准文档

  • $frame->finish, 表示数据帧是否完整,一个WebSocket请求可能会分成多个数据帧进行发送(底层已经实现了自动合并数据帧,现在不用担心接收到的数据帧不完整)

$data 如果是文本类型,编码格式必然是UTF-8,这是WebSocket协议规定的

OpCode与数据类型

  • WEBSOCKET_OPCODE_TEXT = 0x1 ,文本数据

  • WEBSOCKET_OPCODE_BINARY = 0x2 ,二进制数据


小问题:如果会话关闭后,cli也关闭了。导致无法访问,你可以尝试下面这个方法:http://www.iwonmo.com/archives/1292.html


Swoole开发文档:https://wiki.swoole.com/wiki/page/397.html

微信小程序WebSocket开发文档:https://developers.weixin.qq.com/miniprogram/dev/api/network-socket.html

NGINX配置:

nginx.zip



微信小程序WebSocket开发


本站如无特别说明即为原创,转而告知:(https://www.iwonmo.com/archives/1289.html)

标签: 微信小程序, swoole, WebSocket

已有 5 条评论

  1. 小白 小白 回复 2019-08-14 09:47

    nginx的反射端口

  2. 连 连 回复 2018-09-08 23:28

    麻烦给个nginx配置代码,173898243@qq.com,谢谢

    1. 王And木 王And木 回复 2018-09-09 00:39

      已发

  3. katysun katysun 回复 2018-06-01 10:11

    不会配置nginx

    1. 王And木 王And木 回复 2018-06-01 17:06

      很简单的。

添加新评论