微信小程序+webSocket一对一客服聊天

直接上代码

chat.wxml

<!--pages/chat/chat.wxml-->
<view class="chat-all">
    <block wx:for="{{msgList}}" wx:for-item="val">
        <view class="{{val['type']=='consumer'?'chat-message-left':'chat-message-right'}}">
            <image src="{{val['type'] == 'consumer'?server['avatar_url']:mySelf['avatar_url']}}" class="message-avatar"></image>
            <view class="message-nickname"> {{val['type'] == 'consumer'?server['nickname']:mySelf['nickname']}} </view>
            <view class="{{val['type'] == 'consumer'?'message-content-left':'message-content-right'}}"> {{val['content']}} </view>
        </view>
    </block>
</view>
<view class="chat-input">
    <view>
        <image src="../../static/face.png" class="chat-input-left"></image>
    </view>
    <view> <input type="text" class="chat-input-right" bindconfirm="sendMessage" value="{{inputVal}}" confirm-type="send" /> </view>
</view>

chat.wxss

/* pages/chat/chat.wxss */
.chat-all{
  width: 100%;
  height: 1148rpx;
  background-color: #F1F1F1;
  }
  .chat-input{
  width: 100%;
  height: 135rpx;
  background-color: #F1F1F1;
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-direction: row;
  border-top: 1rpx solid #aaaaaa;
  }
  .chat-input-left{
  width: 60rpx;
  height: 60rpx;
  }
  .chat-input-right{
  width: 560rpx;
  height: 59rpx;
  background-color: white;
  border-radius: 50rpx;
  padding: 5rpx 20rpx;
  }
  .chat-message-left,.chat-message-right{
  width: 100%;
  height: 110rpx;
  background-color: orange;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-bottom: 30rpx;
  }
  .chat-message-right{
  display: flex;
  flex-direction: row-reverse;
  }
  .message-avatar{
  width: 86rpx;
  height: 86rpx;
  border-radius: 50%;
  }
  .message-nickname{
  font-size: 23rpx;
  color: #666666;
  }
  .message-content-right{
  background-color: #AAEA7C;
  padding: 18rpx 10rpx;
  border-radius: 30rpx;
  }
  .message-content-left{
  background-color: white;
  padding: 18rpx 10rpx;
  border-radius: 30rpx;
  }

chat.js

Page({
  // 页面的初始数据
  data: {
    mySelf: [],
    server: [],
    msgList: [],
    inputVal: '',
  },
  // 生命周期函数--监听页面加载
  onLoad: function (options) {
    this.connectServer()
    this.chatInfo()
    this.receiveMessage()
    this.sendWebSocketJump()
  },
  onUnload: function () {
    wx.closeSocket()
  },
  connectServer: function () {
    wx.connectSocket({
      url: 'ws://**.***.**:9501?user_id=' + 10,
      success: function () {
        console.log('websocket连接成功');
      },
      fail: function () {
        console.log('websocket连接失败');
      }
    })
  },
  chatInfo: function () {
    // 自己用户信息和客服信息
    let userinfo = wx.getStorageSync('userinfo')
    let mySelf = {
      uid: 10,
      avatar_url: userinfo.avatar_url,
      nickname: '客服小姐姐'
    }
    let server = {
      uid: 1,
      avatar_url: '../../static/server.png',
      nickname: '客户'
    }
    // 初始化客服消息
    let msg = [{
      uid: 10,
      content: '您好,请问有什么可以帮您的嘛?',
      type: "server"
    }]

    this.setData({
      mySelf: mySelf,
      server: server,
      msgList: [...this.data.msgList, ...msg]
    })
  },
  sendMessage: function (event) {
    let content = event.detail.value
    this.setData({
      inputVal: ''
    })
    let msg = [{
      uid: this.data.server.uid,
      toid: this.data.mySelf.uid,
      type: "server",
      content: content,
    }]
    this.setData({
      msgList: [...this.data.msgList, ...msg]
    })
    msg = {
      uid: this.data.mySelf.uid,
      toid: this.data.server.uid,
      type: "server",
      content: content,
    }
    this.sendWebSocketJump(30000, false)
    wx.sendSocketMessage({
      data: JSON.stringify(msg),
      success: res => {
        console.log('发送成功');
        this.sendWebSocketJump(30000, true)
      }
    })
  },
  receiveMessage: function () {
    wx.onSocketMessage((result) => {
      this.setData({
        msgList: [...this.data.msgList, ...[JSON.parse(result.data)]]
      })
      console.log('接收到新消息');
    })
  },
  // 心跳
  sendWebSocketJump: function (time = 30000, status = true) {
    var timing;
    if (status == true) {
      timing = setInterval(function () {
        console.log('当前心跳已重新连接');
        // 循环执行代码
        wx.sendSocketMessage({
          data: JSON.stringify({
            type: 'heart'
          }),
          fail(res) {
            // 关闭连接
            wx.closeSocket()
            wx.showToast({
              title: '当前聊天已断开',
              icon: "none"
            })
            clearInterval(timing)
            console.log('当前心跳已关闭');
          }
        })
      }, time) // 循环时间 不要超过1分钟
    } else {
      clearInterval(timing)
      console.log('当前心跳已关闭');
    }
  }
})

服务端(创建一个.php文件)记得把端口号修改一下

<?php
class Server
{
    const HOST = '0.0.0.0';
    const PORT = 9501;
    private $server = null;
    private $redis = null;
    private $userId = null;

    public function __construct()
    {
        $this->server = new swoole_websocket_server(self::HOST,self::PORT);
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1',6379);
        
        // 方法的调用
        $this->server->on('open',[$this,'onOpen']);
        $this->server->on('message',[$this,'onMessage']);
        $this->server->on('close',[$this,'onClose']);
        $this->server->start();
    }
    public function onOpen($server,$request){
        $userId = $request->get['user_id'];
        $this->redis->set('talk'.$userId,$request->fd);
        $this->userId = $userId;
        echo "用户Id->".$userId.'客户端标识'.$request->fd.'连接成功'.PHP_EOL;
    }
    public function onMessage($server,$frame){
    $data = json_decode($frame->data,true);

    // 心跳检测
    if($data['type'] == 'heart'){
        echo "这是心跳".PHP_EOL;
        return;
    }

    $toFd = $this->redis->get('talk'.$data['toid'])?:null;
    if (empty($toFd)){
        $this->server->push($frame->fd,json_encode([
        'type'=>'server',
        'content'=>'亲,对方暂时不在线,请稍后再试!'
        ]));
        return;
    }
    $this->server->push($toFd,json_encode([
        'uid'=>$data['uid'],
        'type'=>$data['type'],
        'content'=>$data['content'],
        ]));
    }
    public function onClose($server,$fd){
    $userId = $this->userId;
    $this->redis->del('talk'.$userId);
    echo "用户Id->".$userId.'客户端标识'.$fd.'已断开'.PHP_EOL;
    }
}
$obj = new Server();

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值