php5.6+javascript
swoole擴展php
實現簡單的廣播, 支持身份驗證java
廢話少說,上代碼.web
<?php namespace church; use ReflectionClass; use ReflectionException; use Swoole\Websocket\Server; class WebSocket { public $host; public $port; public $config; public $beforeAuthCallback = ''; public $afterAuthCallback = ''; public $beforeSendMsgCallback = ''; public $afterSendMsgCallback = ''; public $authenticator = ''; public $customers = []; protected $server; public function __construct($host = '0.0.0.0', $port = 9501, $config = []) { $this->host = $host; $this->port = $port; $this->config = $config; $this->init(); } public function init() { $this->server = new Server($this->host, $this->port); !empty($this->config) && $this->server->set($this->config); $this->beforeSendMsgCallback = function() {}; $this->afterSendMsgCallback = function() {}; $this->beforeAuthCallback = function() {}; $this->afterAuthCallback = function() {}; $this->authenticator = function() {}; $this->bindEvents(); } public function bindEvents() { $this->server->on('open', [$this, 'onOpen']); $this->server->on('message', [$this, 'onMessage']); $this->server->on('close', [$this, 'onClose']); } public function run() { $this->server->start(); } public function onOpen(Server $server, $request) { call_user_func($this->beforeAuthCallback, $server, $request); if (!$this->auth($request)) { return; } $this->customers[] = $request->fd; call_user_func($this->afterAuthCallback, $server, $request); } public function onMessage(Server $server, $frame) { call_user_func($this->beforeSendMsgCallback, $server, $frame); $this->broadcast($frame->fd, $frame->data); call_user_func($this->afterSendMsgCallback, $server, $frame); } public function onClose($ser, $fd) { $key = array_search($fd, $this->customers); unset($this->customers[$key]); } public function __call($method, $params) { $class_name = get_class($this->server); $class = new ReflectionClass($class_name); try { $class->getMethod($method); } catch (ReflectionException $e) { echo "Method $method is not exists\n"; return; } call_user_func_array([$this->server, $method], $params); } public function broadcast($fromUser, $messages) { $users = array_diff($this->customers, [$fromUser]); foreach ($users as $user) { $this->server->push($user, $messages); } } private function auth($request) { if (($result = call_user_func($this->authenticator, $request)) === false) { $this->server->push($request->fd, "auth failed"); $this->server->close($request->fd); } return $result; } }
<?php require './vendor/autoload.php'; use church\WebSocket; $server = new WebSocket('0.0.0.0', 9501, [ 'daemonize' => 1, ]); $server->authenticator = function($request) use ($server) { $get = $request->get; return empty($get) || ($get['access_token'] == 'access_token'); }; $server->afterAuthCallback = function($ser, $request) use ($server) { $server->push($request->fd, "auth successful"); }; $server->run();
php index.php #就會以守護進程方式運行
客戶端js代碼:shell
var websocket = new WebSocket("ws://192.168.2.106:9501?access_token=access_token"); websocket.onopen=function(evt) { }; websocket.onmessage = function(evt) { console.log(evt); }; websocket.onclose = function(evt) { console.log(evt); };
搭建過程很是方便。實現的比較簡陋,可是能夠知足通常的需求了。支持身份驗證功能,驗證不經過會自動踢掉。websocket