thinkphp5下使用WebSocket_gzmyh的博客-CSDN博客_thinkphp websocket

来源: thinkphp5下使用WebSocket_gzmyh的博客-CSDN博客_thinkphp websocket

最近有个项目需求是这样的:软件端会向服务器发送请求,获取一些信息。然后对获取过来的信息进行处理,再返回信息的id

方式一:软件端那边调用接口,一分钟请求一次。

问题出现:如果有几万个人同时用软件,就会产生大量的http请求,导致负载过高。因此需求考虑到第二种方式。

方式二:使用WebSocket,进行一次长连接,这样就减少了大量的请求。

因为对于webscoket要求不高,因此就选择了Workerman,这也是thinkphp5封装好的扩展,直接下载下来用。

参考手册:thinkphp5.1和workerman开发手册

下面开始:

使用composer下载:

composer require topthink/think-worker
下载下来后会有一些文件,重点看config里面的worker.php和worker_server.php。这两个是不同的监听配置,我使用的是worker_server.php

它的默认配置是这样的

return [
// 扩展自身需要的配置
‘protocol’ => ‘websocket’, // 协议 支持 tcp udp unix http websocket text
‘host’ => ‘0.0.0.0’, // 监听地址
‘port’ => 2346, // 监听端口
‘socket’ => ‘hd.com:2346’, // 完整监听地址
‘context’ => [], // socket 上下文选项
‘worker_class’ => ”, // 自定义Workerman服务类名 支持数组定义多个服务

// 支持workerman的所有配置参数
‘name’ => ‘thinkphp’,
‘count’ => 4,
‘daemonize’ => false,
‘pidFile’ => Env::get(‘runtime_path’) . ‘worker.pid’,

// 支持事件回调
// onWorkerStart
‘onWorkerStart’ => function ($worker) {

},
// onWorkerReload
‘onWorkerReload’ => function ($worker) {

},
// onConnect
‘onConnect’ => function ($connection) {

},
// onMessage
‘onMessage’ => function ($connection, $data) {
$connection->send(‘你成功了’);
},
// onClose
‘onClose’ => function ($connection) {

},
// onError
‘onError’ => function ($connection, $code, $msg) {
echo “error [ $code ] $msg\n”;
},
];
这时你打开命令行(cmd),切换到你项目根目录下

E:\wamp64\www\hd\v2018>E:\wamp64\bin\php\php7.0.4\php.exe think worker:server

因为我没有配置php的环境变量,所有就时候这种方式了。这时会看到这样的结果说明服务启动成功

 

打开chrome浏览器,按F12打开调试控制台,在Console一栏输入(或者把下面代码放入到html页面用js运行)

// 假设服务端ip为127.0.0.1
ws = new WebSocket(“ws://127.0.0.1:2000”);
ws.onopen = function() {
alert(“连接成功”);
};
ws.onmessage = function(e) {
alert(“收到服务端的消息:” + e.data);
};
这是你会收到“你成功了”的字样。

接下来就是真正的开发流程了。

一般情况下我们会创建一个服务类(必须要继承 think\worker\Server),然后设置属性和添加回调方法,这是我写的一个类

<?php
// +———————————————————————-
// | websocket
// +———————————————————————-
// | Author: myh
// +———————————————————————-

namespace app\worker;

use think\worker\Server;
use app\common\api\BaseApi;

class Worker extends Server
{
protected $socket = ‘http://0.0.0.0:2346’;

public function onMessage($connection,$data)
{
$data = explode(‘|’, $data);
switch ($data[0]) {
case ‘software_send_msg’:
if(!isset($data[1]) || empty($data[1])) {
$list = json_encode([‘result’=>’error’,’message’=>’参数为空’]);
}else{
$account = $data[1];
$uid = BaseApi::findData(8,2,[[‘user_login’,’=’,$account]],’id’);

if($uid){
list($data) = BaseApi::getListOne(16,[[‘user_id’,’=’,$uid],[‘status’,’=’,0]]);//16-software_send_msg
if($data){
$list = [];
foreach ($data as $k => $v) {
$list[$k][‘id’] = $v[‘id’];
$list[$k][‘type’] = $v[‘type’];
$list[$k][‘msg’] = $v[‘msg’];
}

$list = json_encode([‘result’=>’success’,’data’=>json_encode($list)]);
}else{
$list = json_encode([‘result’=>’error’, ‘message’=>’数据为空’]);
}

}else{
$list = json_encode([‘result’=>’error’, ‘message’=>’找不到该账号信息’]);
}
}

break;

case ‘software_send_msg2’:
$msg = 3333;
break;

default:
$list = json_encode([‘result’=>’error’]);
break;
}

$connection->send($list);//这里把数据发送给客户端

}

}
这时要对worker_server.php进行修改,删掉之前的配置,只要加上这个即可

return [
‘worker_class’ => ‘app\worker\Worker’,
];
控制器:

public function ws()
{
return $this->fetch(‘:ws’);
}
模板:

<!DOCTYPE html>
<html xmlns:v-on=”http://www.w3.org/1999/xhtml”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>
<title>ThinkCMF WebSocket Demo</title>

<script src=”__STATIC__/js/JQuery-2.0.3.min.js”></script>
</head>
<body>

<div id=”app”>
软件模拟获取最新消息:
<button class=”get-msg”>请求</button>

<div class=”return-msg”>

</div>
</div>

<script>

$(document).on(‘click’,’.get-msg’,function(){
ws = new WebSocket(“ws://127.0.0.1:2346”);

//组织参数
var param = new Array();
param.push(‘software_send_msg’);
param.push(‘wydyhdzh’);

ws.onopen = function() {
ws.send(param.join(‘|’));//向服务器返送信息
};

ws.onmessage = function(e) {//服务器返回信息
var data = JSON.parse(e.data);

if(data.result == ‘success’){
var list = JSON.parse(data.data);
$(‘.return-msg’).html(data.data);
}
};
})

</script>
</body>
</html>

 

整个流程就是这样,不明白可以留言
————————————————
版权声明:本文为CSDN博主「gzmyh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gzmyh/article/details/89874357

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏