swoole做PHP服务器,用Swoole快速搭建一个推送服务器

环境

php5.6+

swoole扩展

需求

实现简单的广播, 支持身份验证

源码

废话少说,上代码.

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;

}

}

使用实例

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代码:

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

};

搭建过程非常方便。实现的比较简陋,但是可以满足一般的需求了。支持身份验证功能,验证不通过会自动踢掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值