websocket 应用实例
来源:互联网 发布:mac版软件下载工具 编辑:程序博客网 时间:2024/06/16 06:54
1. 服务端
class WebSocketServer{ public $server; public function __construct($controller) { $this->server = new \swoole_websocket_server("0.0.0.0", 9501); $this->server->set(array( 'worker_num' => 8, 'daemonize' => false,// 'heartbeat_check_interval' => 30,// 'heartbeat_idle_time' => 90, 'heartbeat_check_interval' => 60, 'heartbeat_idle_time' => 600, )); $this->server->on('WorkerStart', array($controller, 'onWorkerStart')); $this->server->on('open', array($controller, 'onOpen')); $this->server->on('message',array($controller, 'onMessage') ); $this->server->on('close',array($controller, 'onClose') ); $this->server->on('request', array($controller, 'onRequest')); $this->server->on('Timer', array($controller, 'onTimer')); } public function start(){ $this->server->start(); }}class ServerController extends Controller{ private $fdKey='swoole_websocket_server_fd'; private $userIdKey='swoole_websocket_server_userId'; const GPS_POINT_KEY = "GPS:GPSPOINT"; // 实时坐标点的标识 public function start() { try{ $server = new WebSocketServer($this); $server->start(); }catch(\Exception $e) { $this->log("websocket:Caught exception000:".$e->getMessage()); } } public function onWorkerStart( $server , $worker_id) { // 在Worker进程开启时绑定定时器 echo "onWorkerStart\n"; // 只有当worker_id为0时才添加定时器,避免重复添加 if ($worker_id == 0) { $server->addtimer(1000); } } public function onTimer($server, $interval) { switch( $interval ) { case 1000: {// echo "Do Thing A at interval 30000\n"; $this->pushData($server); break; } } } public function onOpen(\swoole_websocket_server $server, $request) { echo "server: handshake success with fd{$request->fd}\n"; try{ $server = $request->server; $uri = trim($server['request_uri'],'/'); $user = explode('/',$uri); $userId = $user[1]; $redis = Cache::getInstance(); $fdArr = $redis->get($this->fdKey.$userId); $fd = $request->fd; if(!empty($fdArr)){ array_push($fdArr,$fd); $newFdArr = $fdArr; }else{ $newFdArr = array($fd); } $redis->set($this->fdKey.$userId,$newFdArr); $redis->set($this->userIdKey.$fd,$userId); $this->log("websocket:server start, fd:".$request->fd); }catch(\Exception $e) { $this->log("websocket:Caught exception000:".$e->getMessage()); } } public function onMessage(\swoole_websocket_server $server, $frame) { echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n"; try{ $data = $frame->data; if($data=='close'){ $redis = Cache::getInstance(); $key = $this->userIdKey.$frame->fd; $userId = $redis->get($key); $redis->rm($key); $redis->rm($this->fdKey.$userId); } }catch(\Exception $e){ $this->log("websocket:Caught exception111:".$e->getMessage()); } } public function onClose($ser,$fd) { echo "client {$fd} closed\n"; $redis = Cache::getInstance(); $redis->rm('swoole_websocket_server_fd1'); $key = $this->userIdKey.$fd; $userId = $redis->get($key); $redis->rm($key); $fdKey = $this->fdKey.$userId; //团队下的fd $fdArr = $redis->get($fdKey); if(!empty($fdArr)&&in_array($fd,$fdArr)){ $fd = arrray($fd); $newFdArr = array_diff($fdArr,$fd); if(!empty($newFdArr)){ $redis->set($fdKey,$newFdArr); }else{ $redis->rm($fdKey); } } $this->log("websocket:server close:".date("Y-m-d H:i:s")); } public function onRequest($request, $response) { // 接收http请求从get获取message参数的值,给用户推送 // $this->server->connections 遍历所有websocket连接用户的fd,给所有用户推送 foreach ($this->server->connections as $fd) { $this->server->push($fd, $request->get['message']); } } public function pushData($server){ $redis = Cache::getInstance(); $all = $redis->hGetAll(self::GPS_POINT_KEY); foreach($all as $key=>$val){ if(!empty($val)){ list($lonlat, $gateTime) = explode('|', $val); list($lon, $lat) = explode(',', $lonlat); $latitude = "$lat"; $longitude = "$lon"; if($gateTime+60>time()){//60s内的算坐标更新了 if(strlen($key)==11){ //手机 //取得对应在线手机所在的团队id $where = ['id_card'=>$key,'state'=>1]; }elseif(strlen($key)==15){ //定位神器 //取得对应在线手机所在的团队id $where = ['device_imei'=>$key,'state'=>1]; } $deviceData = PointDeviceService::getOnlineDevice($where); $deviceData['record'] = [ 'gate_time'=>date("Y-m-d H:i:s", $gateTime), 'latitude'=>$latitude, 'longitude'=>$longitude, ]; print_r($deviceData); $jsonData = json_encode($deviceData); echo $userId = $deviceData['user_id'];//团队ID $fdArr = $redis->get($this->fdKey.$userId); echo "aaa:";print_r($fdArr); if(!empty($fdArr)){ foreach($fdArr as $fd){ $server->push($fd,$jsonData); } } $this->log("websocket:server push data:".$jsonData); }else{ $this->log("websocket:".$key."设备没有更新的坐标数据"); } } } } private function log($message=''){ $trueDir = RUNTIME_PATH.'websocketServer'.DIRECTORY_SEPARATOR; if(!is_dir($trueDir)){ mkdir($trueDir,0777,true); } $file = date('Y_m_d').'.log'; $trueFile = $trueDir.$file; $message = date("Y-m-d H:i:s").":".$message; file_put_contents($trueFile,$message.PHP_EOL,FILE_APPEND); }}
2. 客户端
function wsConnect(){ // var userId = '{userId}'; var wsServer = 'ws://127.0.0.1:9501/user_id/1'; var websocket = new WebSocket(wsServer); return websocket; } //在地图上动态显示所有在线设备 add by mzc 2017.10.19 function dynamicDisplay(){ websocket = wsConnect(); websocket.onopen = function (evt) { if(websocket.readyState==1){ websocket.send('user_id=1'); console.log("websocket连接成功"); } }; websocket.onclose = function (evt) { console.log("Disconnected"); if(websocket.readyState==3){ websocket.send('close'); wsConnect(); console.log('reconnect'); } }; websocket.onmessage = function (evt) { console.log('服务器推送过来的数据: ' + evt.data); var data = evt.data; data = eval('(' + data + ')'); var temp = [];// for (var i = 0; i <data.length; i++) {// temp.push(data[i]);// } temp.push(data); openInfo(temp); }; websocket.onerror = function (evt, e) { console.log('Error occured: ' + evt.data); if(websocket.readyState==3){ wsConnect(); console.log('reconnect'); } }; //关闭页面时记得一定要关闭连接,否则服务端可能不会释放 window.onunload = function(){ websocket.close(); }; }
阅读全文
0 0
- websocket 应用实例
- WebSocket详解(二)应用实例
- 【WebSocket】WebSocket经典实例
- websocket实例
- WebSocket实例
- WebSocket通信实例
- Java Websocket实例
- webSocket 简单实例
- HTML5 WebSocket 简单实例
- 关于websocket小实例
- WebSocket的进一步实例
- websocket简单实例
- websocket与Java实例
- Spring4+WebSocket实例
- Java Websocket实例
- Java Websocket实例
- Websocket 入门学习实例
- Dojo WebSocket 应用
- Oracle中采用sqlplus登录
- 设计模式六大原则(1)---单一职责原则
- mmap多进程拷贝大文件
- python学习:第一个程序猜数字小游戏~包含次数限制、用户输入类型限制。内容学习源于【小甲鱼python入门学习】
- Zookeeper 概述
- websocket 应用实例
- MySql(一、MySQL基础、库操作和表操作)
- 提升语义分割性能的几种方法
- linux下最好用的mplayer播放器使用方法(转)
- SQL学习之--《SQL必知必会》
- 遗传算法小示例
- UVA10282 map容器使用
- WordPress显示评论者IP归属地、浏览器、终端设备、电信运营商
- python基础学习三