tp6引入websocket进行消息推送

下载websocket

composer require topthink/think-worker

创建websocket类

在项目的控制器中,新建一个websocket.php文件,里面写上:

<?php
namespace app\shop\controller;
use think\worker\Server;
use Workerman\Lib\Timer;
define('HEARTBEAT_TIME', 20);// 心跳间隔55秒
class Worker extends Server{
    
    protected $socket = 'websocket://0.0.0.0:2345';
    
    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data){
        
        // echo '后台收到前台的信息';
        
        // echo $data;
        
        if($data === 'ping'){
            
            $connection->send('pong');
            
        }else{
            
            $connection->send('你给我发送了'.$data.','.'我返回给你一坨狗屎');
            
        }
        
    }
    
    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect ($connection) {
 
    
 
    }
    
    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose ($connection) {
 
 
 
    }
    
    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
    */
    public function onError ($connection, $code, $msg) {
        
        echo "error $code $msg\n";
        
    }
    
    /**
     * 每个进程启动
     * @param $worker
    */
    public function onWorkerStart ($worker) {
        
        
 
    }
    
}

我是在宝塔中创建,如果2345端口没开,可以在宝塔中开启下,也可以在config\worker_server.php下修改端口号与socket完整监听地址
在config\worker_server.php引入刚刚创建的websocket类
在这里插入图片描述

配置完成之后在启动下socket:

php think worker:server

在这里插入图片描述
这样就配置完成了。

前端连接websocket

我是用uniapp做了一个demo,其中包含断开重连,心跳机制:
新建一个websocket.js文件,写入

class webSocketClass {
  constructor(url = '你的socket地址', time = 600) {
    this.url = url
    this.data = null
    this.isCreate = false // WebSocket 是否创建成功
    this.isConnect = false // 是否已经连接
    this.isInitiative = false // 是否主动断开
    this.timeoutNumber = time // 心跳检测间隔
    this.heartbeatTimer = null // 心跳检测定时器
    this.reconnectTimer = null // 断线重连定时器
    this.socketExamples = null // websocket实例
    this.againTime = 3 // 重连等待时间(单位秒)
  }

  // 初始化websocket连接
  initSocket() {
    const _this = this
    this.socketExamples = uni.connectSocket({
      url: _this.url,
      header: {
        'content-type': 'application/json'
      },
      success: (res) => {
        _this.isCreate = true
        console.log(res)
      },
      fail: (rej) => {
        console.error(rej)
        _this.isCreate = false
      }
    })
    this.createSocket()
  }

  // 创建websocket连接
  createSocket() {
    if (this.isCreate) {
      console.log('WebSocket 开始初始化')
      // 监听 WebSocket 连接打开事件
      try {
        this.socketExamples.onOpen(() => {
          console.log('WebSocket 连接成功')
          this.isConnect = true
          clearInterval(this.heartbeatTimer)
          clearTimeout(this.reconnectTimer)
          // 打开心跳检测
          this.heartbeatCheck()
        })
		
        // 监听 WebSocket 接受到服务器的消息事件
        this.socketExamples.onMessage((res) => {
          console.log('收到消息')
          uni.$emit('message', res)
        })
		
        // 监听 WebSocket 连接关闭事件
        this.socketExamples.onClose(() => {
          console.log('WebSocket 关闭了')
          this.isConnect = false
          this.reconnect()
        })
		
        // 监听 WebSocket 错误事件
        this.socketExamples.onError((res) => {
          console.log('WebSocket 出错了')
          console.log(res)
          this.isInitiative = false
        })
      } catch (error) {
        console.warn(error)
      }
    } else {
      console.warn('WebSocket 初始化失败!')
    }
  }

  // 发送消息
  sendMsg(value) {
    const param = JSON.stringify(value)
    return new Promise((resolve, reject) => {
      this.socketExamples.send({
        data: param,
        success() {
          console.log('消息发送成功')
          resolve(true)
        },
        fail(error) {
          console.log('消息发送失败')
          reject(error)
        }
      })
    })
  }

  // 开启心跳检测
  heartbeatCheck() {
    console.log('开启心跳')
    this.data = { state: 1, method: 'heartbeat' }
    this.heartbeatTimer = setInterval(() => {
      this.sendMsg(this.data)
    }, this.timeoutNumber * 1000)
  }

  // 重新连接
  reconnect() {
    // 停止发送心跳
    clearTimeout(this.reconnectTimer)
    clearInterval(this.heartbeatTimer)
    // 如果不是人为关闭的话,进行重连
    if (!this.isInitiative) {
      this.reconnectTimer = setTimeout(() => {
        this.initSocket()
      }, this.againTime * 1000)
    }
  }

  // 关闭 WebSocket 连接
  closeSocket(reason = '关闭') {
    const _this = this
    this.socketExamples.close({
      reason,
      success() {
        _this.data = null
        _this.isCreate = false
        _this.isConnect = false
        _this.isInitiative = true
        _this.socketExamples = null
        clearInterval(_this.heartbeatTimer)
        clearTimeout(_this.reconnectTimer)
        console.log('关闭 WebSocket 成功')
      },
      fail() {
        console.log('关闭 WebSocket 失败')
      }
    })
  }
}

export default webSocketClass

然后在页面中使用:

<template>
	<view class="container fs_middle">
		<view class="flex around middle p_20 sizing">
			<u--input placeholder="请输入内容" border="surround" v-model="keyword"></u--input>
			<u-button type="primary" size="small" text="发送消息" color="#ffbf00" @click="sendMessage"></u-button>
		</view>
		
		<view class="mt_20 box_center p_20 sizing bc_white b_r_10">
			<view class="blod fs_big">
				<text>服务端返回消息:</text>
			</view>
			<view class="mt_20">
				<text>{{ content }}</text>
			</view>
		</view>
	</view>
</template>

<script>
	import webSocketClass from '@/utils/websocker2.js'
	export default{
		data () {
			return {
				webSocketTask: null,
				keyword: '',
				content: ''
			}
		},
		
		onLoad(){
		    // this.socket()
			this.webSocketTask = new webSocketClass();
			this.webSocketTask.initSocket();
			uni.$on('message', this.getMessage);
		},
		
		onUnload () {
			uni.$off('message', this.getMessage);
		},
		
		methods: {
			
			// // 发送消息至服务端
			sendMessage () {
				this.webSocketTask.sendMsg(this.keyword);
			},
			
			getMessage(res) {
				this.content = res.data;
			}
		},
	}
</script>

<style lang="scss" scoped>
	/deep/ .u-button{
		width: 120rpx;
		height: 76rpx;
		margin-left: 20rpx;
	}
</style>

这样就可以前端发送一条消息,后台接收到,就会返回前端一条消息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值