您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > 小程序

如何在小程序中实现 WebSocket 通信

时间:2020-03-09 14:42:08  来源:  作者:

在以前的文章中,我们介绍了HTTP通讯,这种通讯有一个缺点,如果我想从直接从服务器发消息给客户端,需要客户端先发起HTTP请求后服务器才能返回数据,且后续服务器想发送数据给客户端都需要客户端先发起请求,但这种方案在一些特殊场景应用的时候非常消耗资源,比如聊天室,如果使用HTTP请求,需要客户端每隔一段时间就请求一次服务器,再由服务器返回数据。这种传统的模式带来很明显的缺点,即客户端需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

在这种情况下,html5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。WebSocket只需要与服务器进行一次握手,即可实现实时的数据连接,并且传输协议是全双工的,服务器可以随时主动向客户端发送数据,并且WebSocket协议在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小,能明显降低服务器及客户端开销。

我们的小程序也支持WebSocket通信,如果你想为你的小程序实现聊天室、服务器推送、小程序之间数据交互等功能,那就非常有必要搭建一个WebSocket服务器来进行WebSocket通讯。这篇文章中,我们将简单介绍小程序WebSocket通信使用方法,并通过实例搭建一个WebSocket服务器。实现小程序与服务器之间的通讯。

在教程开始之前,需要搭建搭建好小程序的基础开发环境,关于如何配置,大家可以参考如何入门小程序开发这篇文章的入门教程。

服务器搭建

既然要实现WebSocket通讯,那必须要拥有一台WebSocket服务器,服务端的环境有很多选择NodeJS、phpPython等大部分主流语言都可以部署WebSocket服务,今天我们将教大家使用PHP语言进行环境部署,其他语言请同学们自行部署。

运行环境搭建

我这里以Ubuntu Server 16.04 LTS为例,我们需要安装php运行环境及NginxWeb服务,同时也需要申请免费的SSL证书和域名,关于证书和域名的申请注册请参考如何快速搭建微信小程序这篇文章。注册完域名及证书申请,我们就可以开始部署服务器了!首先,登录服务器,执行下面的命令。

sudo apt update
sudo apt install php php-fpm php-curl nginx composer -y

安装完成后,使用浏览器访问你的服务器IP地址,如果看到下面的内容,则证明Web服务已经启动。

 

如何在小程序中实现 WebSocket 通信

 

img

因为小程序获取远程数据,必须为HTTPS或WSS环境,所以目前搭建的环境,在小程序无法使用,接下来,我们将使用SSL证书加密小程序访问你服务器之间的流量。这里就需要刚才注册的域名及证书了。首先,将下载的证书,上传到你的服务器,并记录下这个位置。然后,我们将配置Nginx服务,以让其支持WSS流量。

我们找到/etc/nginx/conf.d文件夹,新建配置文件,为了方便后续修改,我将这里的配置文件修改为weixin.techeek.cn.conf大家可以根据自己的需求修改。

cd /etc/nginx/conf.d
sudo nano weixin.techeek.cn.conf

在nano编辑器中,我们写下下面的代码

server {
        listen 443 ssl;
        server_name weixin.techeek.cn;
				index  index.php index.html index.htm;
				root /usr/share/nginx/html;
        ssl_certificate      /home/ubuntu/1_weixin.techeek.cn_bundle.crt;
        ssl_certificate_key  /home/ubuntu/2_weixin.techeek.cn.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location ~ .php$ {
        fastcgi_pass  unix:/run/php/php7.0-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
        location /
        {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        }
}

server {
        listen 80 default_server;
        server_name weixin.techeek.cn;
        root /usr/share/nginx/html;
        index index.php index.html index.htm;
        location / {
                try_files $uri $uri/ =404;
        }
}

一定注意,将文中server_name中的weixin.techeek.cn更换成你的域名。将ssl_certificate和ssl_certificate_key中证书的路径更换成你刚上传证书的路径。然后,执行下面的命令重启nginx服务。

sudo service nginx restart

之后,打开你电脑的浏览器,然后通过域名访问,注意,这里一定要在域名前加https://,比如我访问的域名https://weixin.techeek.cn/。

 

如何在小程序中实现 WebSocket 通信

 

1542188355313

如果域名前有小锁标志,则证明你已经配置成功,可以开始下一步了,这里502报错不用在意,因为我们还没有搭建WebSocket服务,所以服务器会返回502错误。

配置通讯域名

基本环境配置好之后,可以登录 微信公众平台 配置通信域名了。我们点击微信公众号右侧的设置,然后找到服务器域名配置。

 

如何在小程序中实现 WebSocket 通信

 

1542188610710

进入微信公众平台管理后台设置服务器配置,如上图所示,需要将你的服务器域名配置为你自己的域名。我这里的域名是weixin.techeek.cn。

WebSocket服务搭建

上述步骤准备完成后 ,就可以撰写WebSocket服务端的代码了,我这里使用的是PHP socket即时通讯框架Workerman来进行搭建。有了这个框架,我们就可以非常方便的搭建WebSocket服务。因为本文主要讲解小程序端的WebSocket的使用,关于Workerman的详细使用教程,可以参考Workerman官方手册,本文仅做基础环境安装的介绍。

首先,我们创建一个运行WebSocket服务的目录,我这里创建名为php-websocket-server,目录位置可以自定义,我这里就将项目放在ubuntu用户的根目录下。

mkdir /home/ubuntu/php-websocket-server
cd /home/ubuntu/php-websocket-server

接下来,我们使用composer包管理器安装WebSocket运行环境。因为某些原因,国内访问composer可能会报错,所以我们需要使用国内的composer镜像。然后就可以安装Workerman了。

sudo composer config -g repo.packagist composer https://packagist.phpcomposer.com
sudo composer update
sudo composer require workerman/workerman

安装完成后,默认情况下会有三个文件,composer.json、composer.lock、vendor这三个文件,如果没有,请重新执行上面的命令。

├── composer.json
├── composer.lock
└── vendor

安装完workerman依赖文件,我们就可以撰写系统所需的代码了。使用nano编辑器,新建一个可执行的php文件,我这里创建的文件名为webSocket.php,大家可自行更改。

nano webSocket.php

代码如下

<?php
require_once __DIR__ . '/vendor/autoload.php';
use WorkermanWorker;
$ws_worker = new Worker("websocket://0.0.0.0:8080");
$ws_worker->count = 4;
$ws_worker->onMessage = function($connection, $data)
{
    $connection->send('hello ' . $data);
};
Worker::runAll();

这时,一个最基本的websocket服务就编辑完成了,这里的代码意思是,通过/vendor/autoload.php引入Workerman的php文件,然后在8080端口创建websocket服务,并设置进程为4个进程。然后执行onMessage回调函数,该函数接收客户端所发过来的数据$data,然后使用send方法将数据发回给客户端。

接下来,我们就可以运行服务器了,执行下面的代码即可运行。

sudo php webSocket.php start

如果看到类似下面的输出,证明我们websocket服务器已经启动,接下来就可以开始配置小程序端的代码了。

 

如何在小程序中实现 WebSocket 通信

 

1542247109151

小程序端

连接服务器

小程序连接Websocket服务器是通过wx.connectSocket()API进行连接的,为了方便连接API,我们先看看官方的文档。

 

如何在小程序中实现 WebSocket 通信

 

 

我们看到只有url是必填项,其他属性可以不填,那么连接服务器就比较简单了,我们打开index.js文件,写下下面的代码。

Page({
onReady: function () {
	wx.connectSocket({
    url: 'wss://weixin.techeek.cn'
	})
},
})

有小程序开发经验的小伙伴都知道,这里的onReady是小程序的生命周期函数,负责在小程序初次渲染完成后执行的函数,这样我们编译完小程序,小程序就自动连接服务器。现在编译一下试试,咦,好像不行啊,怎么没看到小程序有反应。我们打开控制台,点击Network按钮,如果看到类似下面的内容,就证明你的小程序已经成功链接服务器了。

 

如何在小程序中实现 WebSocket 通信

 

1542249696427

这里的HTTP状态码是101,101状态码是websocket特有的状态码,我们已经成功连接搭建的服务器。但是我们能不能直观点看到已经连接服务器呢?当然可以,参考文档使用success属性,我们在其中加入回调函数。修改代码如下。

Page({
  onReady: function () {
    wx.connectSocket({
      url: 'wss://weixin.techeek.cn',
        success: function (res) {
          console.log("连接服务器成功")
      },
      fail: function (res) {
        console.log("连接服务器失败")
      }
    })
  },
})

我们增加一个回调函数,如果服务器连接成功,向小程序控制台打印出连接服务器成功。反正打印连接服务器失败。

 

如何在小程序中实现 WebSocket 通信

 

1542250247835

当然,我们也可以将成功的内容展示给小程序前端,代码如下,首先修改index.wxml代码。

<view><text>连接服务器状态:{{status}}</text></view>

然后打开index.js文件,修改代码

Page({
  onReady: function () {
    var myThis = this;
    wx.connectSocket({
      url: 'wss://weixin.techeek.cn',
      success: function (res) {
        myThis.setData({
          status: "连接服务器成功"
        })
      },
      fail: function (res) {
        myThis.setData({
          status: "连接服务器失败"
        })
      }
    })
  },
})

现在重新编译小程序,你会看到类似这样的界面。

 

如何在小程序中实现 WebSocket 通信

 

1542250497626

向服务器发送数据

服务器搭建我们说到,我们的服务器的代码内容是将小程序发给服务器的任意字符前加hello之后返回给小程序,现在,我们已经成功连接服务器了。接下来,我们需要修改代码,以便小程序将数据发给服务器。

官方文档中,使用wx.sendSocketMessage()API将数据发给服务器,根据官方文档,通过 WebSocket 连接发送数据。需要先wx.connectSocket连接服务器,并在 wx.onSocketOpen 回调之后才能发送。所以在调用wx.sendSocketMessage()前,需要先调用wx.onSocketOpen监听WebSocket连接是否打开。代码如下。

Page({
  onReady: function () {
    var myThis = this;
    wx.connectSocket({
      url: 'wss://weixin.techeek.cn'
    })
    wx.onSocketOpen(function (res) {
      myThis.setData({
        status: "websocket连接服务器成功"
      })
    })
  },
})

现在,我们就可以使用wx.sendSocketMessage()发送数据到服务器了,先看看官方文档,怎么使用。

 

如何在小程序中实现 WebSocket 通信

 

 

我们只需要传data内容给API,就能发内容给服务器了,那么修代码内容如下。

Page({
    onReady: function () {
    var myThis = this;
    wx.connectSocket({
      url: 'wss://weixin.techeek.cn'
    })
    wx.onSocketOpen(function (res) {
      wx.sendSocketMessage({
        data: "你好",
        success: function (res) {
          console.log("数据已发给服务器")
        }
      })
      myThis.setData({
        status: "websocket连接服务器成功"
      })
    })
  },
})

现在,我们的数据已经可以发给服务器了,可是我们还没有看到服务器返回的数据,这时,我们就该使用另一个API了,监听WebSocket 接受到服务器的消息事件wx.onSocketMessage(),该API返回服务器发出的消息。但是onReady函数是页面加载就运行的,这时服务器还没反应过来,数据返回了没收到该怎么处理?我们可以引入另一个生命周期函数onLoad,这个函数是小程序负责监听页面加载的函数,我们可以将服务器消息事件监听的API写在这里,当接收到数据,由这个函数返回相关内容。所以代码如下。

Page({
  onReady: function () {
    var myThis = this;
    wx.connectSocket({
      url: 'wss://weixin.techeek.cn'
    })
    wx.onSocketOpen(function (res) {
      wx.sendSocketMessage({
        data: "你好",
        success: function (res) {
          console.log("数据已发给服务器")
        }
      })
      myThis.setData({
        status: "websocket连接服务器成功"
      })
    })
  },
  onLoad: function (options) {
    var myThis = this;
    wx.onSocketMessage(function (res) {
      myThis.setData({
        message: res.data
      })
    })
  },
})

为了方便观察服务器返回的数据,我们修改下前端,增加服务器消息监听的内容。

<view><text>连接服务器状态:{{status}}</text></view>
<view><text>服务器消息:{{message}}</text></view>

现在,重新编译,就能看到服务器返回Hello 你好的内容,我们发出的内容为你好,服务器在内容前加一个Hello然后返回给小程序。我们可以修改你好为任意内容,看看服务器能否正常返回相关内容。稍微优化下前端和后端代码,如下。

index.wxml

<button type="primary" bindtap="connect">连接webSocket服务器</button>
<button type="warn" bindtap="close">断开webSocket服务器</button>
<input placeholder="在这里输入你要发送的弹幕内容" bindblur="input"/>
<button bindtap="send">向webSocket服务器发送消息</button>
<view><text>连接服务器状态:{{status}}</text></view>
<view><text>服务器消息:{{message}}</text></view>

index.js

Page({
  connect() {
    var myThis = this;
    wx.connectSocket({
      url: 'wss://weixin.techeek.cn'
    })
    wx.onSocketOpen(function (res) {
      myThis.setData({
        status:"websocket连接服务器成功"
      })
    })
  },
  close(){
    var myThis = this;
    wx.closeSocket()
    wx.onSocketClose(function (res) {
      myThis.setData({
        status: "websocket服务器已经断开"
      })
    })
  },
send(){
  var myThis = this;
  wx.sendSocketMessage({
    data: this.inputValue,
    success: function (res) {
      console.log("发送信息")
      wx.showToast({
        title: '已发送',
        icon: 'success',
        duration: 1000
      })
    },
    fail: function (res) {
      myThis.setData({
        status: "请连接服务器"
      })
    }
  })
},
  input: function (e) {
    this.inputValue = e.detail.value
  },
  onLoad: function (options) {
    var myThis = this;
    wx.onSocketMessage(function (res) {
      myThis.setData({
        message:res.data
      })
      wx.showToast({
        title: '你收到来自服务器的消息',
        icon: 'none',
        duration: 2000
      })
    })
  },
})

 

如何在小程序中实现 WebSocket 通信

 

1542253679047

这样,我们就实现了向服务器发送数据,同时服务器返回数据的全部流程。

服务器主动发送数据到小程序

有人可能会问,这个HTTP通信方式没有区别啊,还是小程序先请求数据到服务器,然后服务器返回数据啊,我没看到什么不同。虽然表现是这样,但是现在小程序和服务器是长连接状态,服务器可以直接推送内容到小程序,不信?我们试试。打开你的服务器Websocket.php文件,将代码修改为下面的内容。

<?php
require_once __DIR__ . '/vendor/autoload.php';
use WorkermanWorker;
use WorkermanLibTimer;

$worker = new Worker('websocket://0.0.0.0:8080');
$worker->onWorkerStart = function($worker){
    Timer::add(10, function()use($worker){
        foreach($worker->connections as $connection) {
            $connection->send('你好!');
        }
    });
};

$worker->onMessage = function($connection, $data)
{
    echo $data . "n";
    $connection->send('服务器已经收到了你的消息');
};
Worker::runAll();

然后运行服务器。

sudo php webSocket.php start

这行代码中,我们实现了小程序连接服务器后,服务器每隔10秒主动推送数据你好给小程序,无需小程序主动请求内容,同时,小程序发出的内容,可以在服务端显示。现在点击你小程序连接webSocket服务器按钮,看看效果。

 

如何在小程序中实现 WebSocket 通信

 

然后我们向服务器发点消息试试。服务器也已经收到了小程序发出的数据。

 

如何在小程序中实现 WebSocket 通信

 

总结

websocket通信在小程序端还是比较简单的,赶快去自己试试吧~后续我还会介绍一篇利用websocket通讯进行聊天室搭建的教程



Tags:WebSocket   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
最近工作中需要开发前端操作远程虚拟机的功能,简称 WebShell。基于当前的技术栈为 react+django,调研了一会发现大部分的后端实现都是 django+channels 来实现 websocket 服务。...【详细内容】
2021-09-13  Tags: WebSocket  点击:(52)  评论:(0)  加入收藏
前言:作为一个刚踏入职场的实习生,我很幸运参加了某个政府项目,并且在项目中负责一个核心模块功能的开发,而不是从头到尾对数据库的crud。虽然我一直心里抱怨我的工作范围根本...【详细内容】
2021-05-24  Tags: WebSocket  点击:(231)  评论:(0)  加入收藏
1)通知功能:保持一个长连接,当服务端游新的消息,能够实时的推送到使用方。像知乎的点赞通知、评论等,都可以使用WebSocket通信。某些使用H5的客户端,为了简化开发,也会使用WebSocke...【详细内容】
2021-03-03  Tags: WebSocket  点击:(157)  评论:(0)  加入收藏
背景:一般与服务端交互频繁的需求,可以使用轮询机制来实现。然而一些业务场景,比如游戏大厅、直播、即时聊天等,这些需求都可以或者说更适合使用长连接来实现,一方面可以减少轮询...【详细内容】
2020-12-17  Tags: WebSocket  点击:(156)  评论:(0)  加入收藏
1. 前言Websocket是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送...【详细内容】
2020-11-11  Tags: WebSocket  点击:(100)  评论:(0)  加入收藏
前段时间我有这样一个需求,想和一个异地的人一起看电影,先后在网上找了一些方案,不过那几个案都有一些缺点...【详细内容】
2020-10-21  Tags: WebSocket  点击:(92)  评论:(0)  加入收藏
1. 前言Websocket是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数...【详细内容】
2020-09-18  Tags: WebSocket  点击:(97)  评论:(0)  加入收藏
前言服务器和客户端保持长连接通信,实现方式比较多。有很多成熟的框架可以完成,底层无非都是对Socket流的封装和使用。一、SOCKET原理Socket大致是指在端到端的一个连接中,这...【详细内容】
2020-08-06  Tags: WebSocket  点击:(75)  评论:(0)  加入收藏
1. 心跳重连原由 心跳和重连的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生。websocket连接断开有以下两种情况:前端断开在使用websocket过程中,可能会出现...【详细内容】
2020-07-29  Tags: WebSocket  点击:(308)  评论:(0)  加入收藏
用这些简化了 WebSockets 的开源支持工具来控制你的流媒体。 来源:https://linux.cn/article-12347-1.html 作者:Kevin Sonney 译者:Xingyu.Wang(本文字数:4340,阅读时长大约:6 分...【详细内容】
2020-06-25  Tags: WebSocket  点击:(96)  评论:(0)  加入收藏
▌简易百科推荐
一、项目背景随着小程序在用户规模和商业化上取得的极大成功,各大平台都推出了自己的小程序。然而这些平台的小程序开发在语法上又不尽相同,不同平台小程序代码的维护需要投入...【详细内容】
2021-11-05  携程技术    Tags:小程序   点击:(65)  评论:(0)  加入收藏
作者:灰灰来源:JS每日一题 一、背景传统的web开发实现登陆功能,一般的做法是输入账号密码、或者输入手机号及短信验证码进行登录服务端校验用户信息通过之后,下发一个代表登录态...【详细内容】
2021-10-29  Nodejs开发    Tags:微信小程序   点击:(43)  评论:(0)  加入收藏
总结列举微信小程序开放能力清单 硬件能力 蓝牙 NFC读写 连接WIFI设备 开放能力 ...【详细内容】
2021-09-27  软件开发分享    Tags:微信小程序   点击:(60)  评论:(0)  加入收藏
核心商城(CoreShop)介绍核心小程序商城系统(CoreShop) 是基于 Asp.Net 5.0、Uni-App开发、支持可视化布局的小程序商城系统;前后端分离,支持分布式部署,跨平台运行;拥有分销、代理、...【详细内容】
2021-07-20  码农也有梦想    Tags:小程序商城   点击:(115)  评论:(0)  加入收藏
介绍Vue3发布已经有一段时间了,从目前来看,其生态还算可以,也已经有了各种组件库给予了支持,但是不管是Vue3还是Vue2都无法直接用来开发小程序,因此国内一些技术团队针对Vue开发...【详细内容】
2021-07-13  爱分享Coder    Tags:小程序   点击:(204)  评论:(0)  加入收藏
首先明确几个概念1. W3C:指万维网联盟(World Wide Web Consortium),是一个国际的标准的制定机构。2. H5(HTML5,HyperText Markup Language 5的缩写),HTML5 是由W3C制定的新HTML标...【详细内容】
2021-07-06  畅游零和一的海洋    Tags:微信小程序   点击:(153)  评论:(0)  加入收藏
在开发微信公众号时,需要不时请求URL和数据封装。为了不做重复的工作。提取公共部分进行封装。产生了相应的公众类。今天先来写下请求类,代码如下:public class HttpRequestP...【详细内容】
2021-06-16  java浮萍  今日头条  Tags:公共类   点击:(134)  评论:(0)  加入收藏
小程序上线后,改版了很多次,包括一些 Api 接口也有改动。如果你学习一个很久之前的小程序项目是没有意义的,本文推荐的小程序都是最近有更新的。相信在你学习、部署的过程中,不...【详细内容】
2021-06-08    程序猿久一  Tags:微信小程序   点击:(207)  评论:(0)  加入收藏
自从2019年微信公开课Pro在微信之夜演示《跳一跳》以来,微信小游戏已经不知不觉走过的三年,这三年中我们可以明显看到微信对小游戏的扶持,对于微信开发者来说,微信小游戏开发以...【详细内容】
2021-05-25  开课吧科科  今日头条  Tags:微信小游戏   点击:(212)  评论:(0)  加入收藏
学习编程从hello world开始。学习微信小程序开发首先要安装一个微信开发者工具,官网上免费下载童叟无欺,下载完傻瓜式安装即可。 双击微信开发者工具,然后选择小程序,然后点击...【详细内容】
2021-05-12  程序员fearlazy  fearlazy  Tags:微信小程序   点击:(268)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条