thinkphp5下使用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的环境变量,所有就时候这种方式了。这时会看到这样的结果说明服务启动成功

thinkphp5下使用WebSocket_第1张图片

打开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),然后设置属性和添加回调方法,这是我写的一个类

'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');
}

模板:




    
    
    ThinkCMF WebSocket Demo

    



软件模拟获取最新消息:

整个流程就是这样,不明白可以留言

 

你可能感兴趣的:(thinkphp)