PHP+Swoole实现微信小程序客服即时通信聊天功能

一、PHP7安装Swoole扩展

PHP swoole 扩展下载地址

Github:https://github.com/swoole/swoole-src/tags

php官方扩展库:

开源中国:http://git.oschina.net/swoole/swoole/tags

1、自定义安装

# 下载wget # 解压tar zxf swoole-4.3.3.tgz# 编译安装扩展# 进入目录cd swoole-4.3.3 # 执行phpize命令,产生出configure可执行文件# 如果不知道phpize路径在哪里 可以使用which phpize查看相应路径/usr/bin/phpize # 进行配置如果不知道php-config路径在哪里 可以使用which php-config 查看相应路径./configure --with-php-config=/usr/bin/php-config # 编译和安装make && make install vi /etc/php.ini复制如下代码extension=swoole.so放到你所打开或新建的文件中即可,无需重启任何服务# 查看扩展是否安装成功php -m|grep swoole

2、宝塔面板安装PHP swoole扩展

如果感觉上述安装较为复杂,可以使用宝塔面板实现一键安装

二、配置nginx反向代理

1、使用xshell连接远程阿里云服务器

2、使用命令(find / -name nginx.conf)查找nginx.conf所在的配置文件

3、使用命令(vim /etc/nginx/nginx.conf)查找进入到vim编辑器

查看到可以引入/etc/nginx/conf.d/下的配置文件信息

4、使用命令(cd /etc/nginx/conf.d/)进入到该路径下,并新建配置文件:study.lishuo.net.conf

5、配置nginx反向代理,实现访问study.lishuo.net域名转发端口号到127.0.0.1:9511也就是转发到webscoket运行的端口号

# 反向代理的规则 study 这个名字自己随便起upstream study{server 127.0.0.1:9511;}server {listen 80;server_namestudy.lishuo.net;error_page 404 /404.html;location = /404.html {}location / {index index.php index.html index.htm;if (!-e $request_filename) {rewrite^(.*)$/index.php?s=/$1last;}#wss配置client_max_body_size 100m;proxy_redirect off;proxy_set_header Host $host;# http请求的主机域名proxy_set_header X-Real-IP $remote_addr;# 远程真实IP地址proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#反向代理之后转发之前的IP地址proxy_read_timeout s;#websocket心跳时间,默认是60sproxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";proxy_pass ; }error_page 500 502 503 504 /50x.html;location = /50x.html {} #添加下列信息,配置Nginx通过fastcgi方式处理您的PHP请求。location ~ .php$ {fastcgi_pass 127.0.0.1:9001; #Nginx通过本机的9000端口将PHP请求转发给PHP-FPM进行处理。fastcgi_index index.php;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;include fastcgi_params; #Nginx调用fastcgi接口处理PHP请求。}    }

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

1、登录到开放平台https://mp.weixin.qq.com/

2、开发=>开发管理=>开发设置,完成合法域名设置

3、到此配置已经完成了,接下来就是功能实现了,小程序+PHP代码

四、效果演示和代码

1、小程序端代码

小程序页面代码所在路径 /pages/contact/contact.ml

<!--pages/contact/contact.ml--><view><scroll-view scroll-y scroll-into-view={{toView}} style=height: {{scrollHeight}};><!-- <view class=scrollMsg> --><block :key :for={{msgList}} :for-index="index"><!-- 单个消息1 客服发出(左) --><view :if={{item.speaker=="server"}} id=msg-{{index}} style=display: flex; padding: 2vw 11vw 2vw 2vw;><view style=width: 11vw; height: 11vw;><image style=width: 11vw; height: 11vw; border-radius: 10rpx; src=https://cdn.pixabay.com/photo/2020/02/10/12/47/girl-4836394__340.jpg></image></view><view style=width: 4vw; height: 11vw; margin-left: 0.5vw; display: flex; align-items: center; z-index: 9;><view class="triangle_border_left"></view></view><view class=leftMsg>{{item.content}}</view></view><!-- 单个消息2 用户发出(右) --><view :else id=msg-{{index}} style=display: flex; justify-content: flex-end; padding: 2vw 2vw 2vw 11vw;><view class=rightMsg>{{item.content}}</view><view style=width: 4vw; height: 11vw; margin-right: 0.5vw; display: flex; align-items: center; z-index: 9;><view class="triangle_border_right"></view></view><view style=width: 11vw; height: 11vw;><image style=width: 11vw; height: 11vw; border-radius: 10rpx; src=https://cdn.pixabay.com/photo/2021/09/24/10/00/chick-6652163__340.jpg></image></view></view></block><!-- </view> --><!-- 占位 --><view style=width: 100%; height: 18vw;></view></scroll-view><view class=inputRoom style=bottom: {{inputBottom}}><image style=width: 7vw; margin-left: 3.2vw; src= mode=widthFix></image><input bindconfirm=sendClick adjust-position={{false}} value={{inputVal}} confirm-type=send bindfocus=focus bindblur=blur></input></view></view>

小程序页面样式代码所在路径 /pages/contact/contact.ss

/* pages/contact/contact.ss */page {background-color: #f1f1f1;}.inputRoom {width: 100vw;height: 16vw;border-top: 1px solid #cdcdcd;background-color: #f1f1f1;position: fixed;bottom: 0;display: flex;align-items: center;z-index: 20;}input {width: 76vw;height: 9.33vw;background-color: #fff;border-radius: 40rpx;margin-left: 2vw;padding: 0 3vw;font-size: 28rpx;color: #444;}.leftMsg {font-size: 35rpx;color: #444;line-height: 7vw;padding: 2vw 2.5vw;background-color: #fff;margin-left: -1.6vw;border-radius: 10rpx;z-index: 10;}.rightMsg {font-size: 35rpx;color: #444;line-height: 7vw;padding: 2vw 2.5vw;background-color: #96EB6A;margin-right: -1.6vw;border-radius: 10rpx;z-index: 10;} /*向左*/ .triangle_border_left {width: 0;height: 0;border-width: 10px 30px 30px 0;border-style: solid;border-color: transparent #fff transparent transparent;/*透明 黄 透明透明 */margin: 40px auto;position: relative;}/*向右*/.triangle_border_right {width: 0;height: 0;border-width: 0px 30px 20px 13px;border-style: solid;border-color: transparent transparent transparent #96EB6A;/*透明 透明透明 黄*/margin: 40px auto;position: relative;}

小程序配置文件代码所在路径 /pages/contact/contact.json

{"navigationBarTitleText":"柯作客服","usingComponents": {}}

小程序业务逻辑代码所在路径 /pages/contact/contact.js

// pages/contact/contact.jsconst app = getApp();var inputVal = ;var msgList = [];var windowWidth = .getSystemInfoSync().windowWidth;var windowHeight = .getSystemInfoSync().windowHeight;var keyHeight = 0;/** * 初始化数据 */function initData(that) {//输入框的内容inputVal = ;//消息列表,包含客服和用户的聊天内容msgList = [{speaker: server,contentType: text,content: Hi,亲爱的小主,终于等到您啦!欢迎来到柯作店铺,很荣幸为您服务。},{speaker: customer,contentType: text,content: 你高兴的太早了}]that.setData({msgList,inputVal})}Page({/** * 页面的初始数据 */data: {scrollHeight: 100vh,inputBottom: 0},/** * 生命周期函数--监听页面加载 */onLoad: function(options) {//初始化websocket连接this.chat();//监听心跳的方法this.webSocketXin();//聊天方法initData(this);//监听消息.onSocketMessage(res=>{ //追加到消息列表里msgList.push(JSON.parse(res.data))inputVal = ;this.setData({msgList,inputVal});})},//页面卸载时间onUnload(){.closeSocket();},/** * 获取聚焦 */focus: function(e) {keyHeight = e.detail.height;this.setData({scrollHeight: (windowHeight - keyHeight) + px});this.setData({toView: msg- + (msgList.length - 1),inputBottom: keyHeight + px})//计算msg高度// calScrollHeight(this, keyHeight);},//失去聚焦(软键盘消失)blur: function(e) {this.setData({scrollHeight: 100vh,inputBottom: 0})this.setData({toView: msg- + (msgList.length - 1)})},/** * 发送点击监听 */sendClick: function(e) {//客户发的信息let customerMsg = {uid: 10,speaker: customer,contentType: text,content: e.detail.value}; //关闭心跳包 this.webSocketXin(60000, false)//发送给websocket.sendSocketMessage({data: JSON.stringify(customerMsg),success:res=>{//重启心跳包this.webSocketXin(40000, true)}})//追加到消息列表里msgList.push(customerMsg)inputVal = ;this.setData({msgList,inputVal});},/** * 退回上一页 */toBackClick: function() {.navigateBack({})},/** * websocket */chat(){ //进行连接php的socket .connectSocket({ //wss 协议相当于你要有一个ssl证书,https //ws就相当于不实用证书httpurl: ws://study.lishuo.net,success: function () {console.log(websocket连接成功~)},fail: function () {console.log(websocket连接失败~)}})},/** * 监听websocket心跳连接的方法 */webSocketXin(time=60000,status=true){var timing;if(status == true){timing = setInterval(function () {console.log("当前心跳已重新连接");//循环执行代码.sendSocketMessage({data: JSON.stringify({type: active}),fail(res) {//关闭连接.closeSocket();//提示.showToast({title: 当前聊天已断开,icon:none})clearInterval(timing);console.log("当前心跳已关闭");}});}, time) //循环时间,注意不要超过1分钟} else {//关闭定时器clearInterval(timing);console.log("当前心跳已关闭");}}})

2、服务端代码(PHP代码)

wechat_websocket.php

<?php//创建WebSocket Server对象,监听0.0.0.0:9502端口$ws = new Swoole\WebSocket\Server(0.0.0.0, 9511);//监听WebSocket连接打开事件$ws->on(Open, function ($ws, $request) {echo $request->fd . 我连接上了;});//监听WebSocket消息事件$ws->on(Message, function ($ws, $frame) {//把前台传过来的json字符串转成数组$params = json_decode($frame->data, true);//判断是否是心跳消息,如果是心跳消息if (isset($params[type]) && isset($params[type])==active){echo 这是心跳监听消息;}else{//先判断当前用户有没有正在连接if (isset($params[uid]) && !empty($params[uid] == 666)) {//去用户表查询当前用户fd$fd = 2;} else {$fd = 1;}//客服id$ws->push($fd, json_encode($params, JSON_UNESCAPED_UNICODE));}});//监听WebSocket连接关闭事件$ws->on(Close, function ($ws, $fd) {echo "client-{$fd} is closed\n";});$ws->start();

五、代码已经编写完了

1、把服务端代码上传到Linux操作系统里

2、然后切到该目录下进行运行php wechat_websocket.php

简单分享快乐学习,如有错误请多包涵!