美文网首页程序员
微信小程序WebSocket开发

微信小程序WebSocket开发

作者: 王And木 | 来源:发表于2018-05-31 17:51 被阅读127次

    微信小程序WebSocket开发

    image

    让我们来实现一个简单的微信小程序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的推送,需要注意作用域的问题,面向过程请使用global对swoole_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

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

    • $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

    也可以访问我的博客:http://www.iwonmo.com

    相关文章

      网友评论

      本文标题:微信小程序WebSocket开发

      本文链接:https://www.haomeiwen.com/subject/xwfcsftx.html