php gateway worker,php 使用workerman/gateway制作聊天

这次使用的是laravel框架:

1、安装workerman/gateway-worker

终端项目目录下输入:

composer require workerman/gateway-worker

2、创建workerman启动文件

php artisan make:command Workerman

namespace App\Console\Commands;

use Illuminate\Console\Command;

use GatewayWorker\BusinessWorker;

use GatewayWorker\Gateway;

use GatewayWorker\Register;

use Workerman\Worker;

class Workerman extends Command

{

/**

* The name and signature of the console command.

*

* @var string

*/

protected $signature = 'workerman {action} {--d}';

/**

* The console command description.

*

* @var string

*/

protected $description = 'Start a Workerman server.';

/**

* Create a new command instance.

*

* @return void

*/

public function __construct()

{

parent::__construct();

}

/**

* Execute the console command.

*

* @return mixed

*/

public function handle()

{

//

global $argv;

$action = $this->argument('action');

$argv[0] = 'artisan workerman';

$argv[1] = $action;

$argv[2] = $this->option('d') ? '-d' : ''; //必须是一个-,上面定义命令两个--,后台启动用两个--

$this->start();

}

private function start()

{

$this->startGateWay();

$this->startBusinessWorker();

$this->startRegister();

Worker::runAll();

}

private function startBusinessWorker()

{

$worker = new BusinessWorker();

$worker->name = 'BusinessWorker';

$worker->count = 1;

$worker->registerAddress = '127.0.0.1:1236';

$worker->eventHandler = \App\GatewayWorker\Events::class;

}

private function startGateWay()

{

$gateway = new Gateway("websocket://0.0.0.0:2346");

$gateway->name = 'Gateway';

$gateway->count = 1;

$gateway->lanIp = '127.0.0.1';

$gateway->startPort = 2300;

$gateway->pingInterval = 30;

$gateway->pingNotResponseLimit = 0;

$gateway->pingData = '{"type":"ping"}';

$gateway->registerAddress = '127.0.0.1:1236';

}

private function startRegister()

{

new Register('text://0.0.0.0:1236');

}

}

复制代码

3、创建事件监听文件

创建一个 app/GatewayWorker/Events.php 文件来监听处理 workman 的各种事件

namespace App\GatewayWorker;

use GatewayWorker\Lib\Gateway;

use Illuminate\Support\Facades\Log;

class Events

{

public static function onWorkerStart($businessWorker)

{

echo "onWorkerStart\r\n";

}

public static function onConnect($client_id)

{

Gateway::sendToClient($client_id, json_encode(['type' => 'onConnect', 'client_id' => $client_id]));

// echo $client_id;

echo $client_id."登陆成功\r\n";

}

public static function onWebSocketConnect($client_id, $data)

{

echo "onWebSocketConnect\r\n";

}

public static function onMessage($client_id, $message)

{

Gateway::sendToClient($client_id,$message);

echo $message;

// Gateway::sendToClient($client_id, json_encode(['type' => 'onMessage', 'client_id' => $client_id, 'name' => json_decode($message)->name]));

// echo "onMessage\r\n";

}

public static function onClose($client_id)

{

Log::info('Workerman close connection' . $client_id);

echo "onClose\r\n";

}

}

复制代码

4、测试。启动workerman服务端

php artisan workerman start --d

复制代码

在浏览器 F12 打开调试模式,在 Console 里输入

ws = new WebSocket("ws://ipaddress:2346");

ws.onopen = function() {

ws . send('{"name":"one","user_id":"111"}');

ws . send('{"name":"two","user_id":"222"}');

};

ws.onmessage = function(e) {

console.log("收到服务端的消息:" + e.data);

};

ws.onclose = function(e) {

console.log("服务已断开" );

}

复制代码

console收到服务器端的消息.....

如在控制器里使用,需要

public function __construct()

{

// 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值(ip不能是0.0.0.0)

Gateway::$registerAddress = '127.0.0.1:1236';

}

复制代码

5、长链接使用代码

后端:

namespace App\Http\Controllers\chat;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\Redis;

use App\GatewayWorker\Events;

use GatewayWorker\Lib\Gateway;

class Chat

{

public function __construct()

{

// 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值(ip不能是0.0.0.0)

Gateway::$registerAddress = '127.0.0.1:1236';

}

public function talks()

{

return view('chat.talks');

}

public function talk(Request $request)

{

return view('chat.talk');

}

public function loginConfirm(Request $request)

{

$name = $request->post('name');

if ($name) {

$user = Redis::sAdd('name',$name);

// if ($user) {

return response()->json(['code'=>200]);

// }

}

}

public function getList(Request $request)

{

$to = $request->get('name');

$list = Redis::sMembers('name');

foreach ($list as $k=>$v)

{

$unread = Redis::hGet('unread_'.$to, $v);

$list[$k] = array('name'=>$v, 'unread'=>$unread);

}

if ($list) {

return response()->json(['code'=>200, 'list'=>$list]);

}

}

public function content(Request $request)

{

$client_id = $request->post('client_id');

$content = $request->post('content');

$from = $request->post('from');

$to = $request->post('to');

$plus = strcmp(md5($from), md5($to));

if ($plus == 0) {

$res = $from.$to;

} else if ($plus < 0) {

$res = $from.$to;

} else if ($plus >0) {

$res = $to.$from;

}

$data = json_encode(array('from'=>$from, 'to'=>$to, 'message'=>$content, 'time'=>time()),JSON_UNESCAPED_UNICODE,true);

$keyName = 'mes:'.$res;

$insert = Redis::rPush($keyName, $data);

$unread = Redis::hIncrBy('unread_'.$to,$from,1);

if ($insert&&$unread) {

Gateway::sendToGroup($res,$data);

return response()->json(['code'=>200]);

}

}

public function mesList(Request $request)

{

$from = $request->get('from');

$to = $request->get('to');

$plus = strcmp(md5($from), md5($to));

if ($plus == 0) {

$res = $from.$to;

} else if ($plus < 0) {

$res = $from.$to;

} else if ($plus >0) {

$res = $to.$from;

}

$list = Redis::lrange('mes:'.$res,-10,-1);

foreach( $list as $k=>$v) {

$list[$k] = json_decode($v);

}

Redis::hSet('unread_'.$from, $to, 0);

$client_id = $request->get('client_id');

Gateway::joinGroup($client_id, $res);

return response()->json(['code'=>200, 'list'=>$list]);

}

public function mesRead(Request $request)

{

$from = $request->input('from');

$to = $request->input('to');

Redis::hSet('unread_'.$from, $to, 0);

}

}

复制代码

前端:

content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

《后退

@{{ list.message }}

@{{list.from}}

@{{list.from}}

@{{ list.message }}

var Ca = new Vue({

el:".page",

data(){

return{

content: '',

lists: [],

master: '',

client_id: ''

}

},

created: function(){

this.master = Cookies.get('name');

ws = new WebSocket("ws://www.dzzzh.com:2346");

ws.onmessage = function(e) {

console.log(e)

let eJson = JSON.parse(e.data)

if (eJson.type == "onConnect") {

// Cookies.set('client_id', eJson.client_id)

Ca.client_id = eJson.client_id

Ca.mesList()

}

if (eJson.message){

Ca.lists.push(eJson)

Ca.read()

}

console.log("收到服务端的消息:" + e.data);

};

},

methods:{

back(){

window.location.href="{{url('/talks')}}"

},

send(){

axios.post("{{url('/api/content')}}",{

from: "{{$_GET['name']}}",

to: "{{$_GET['to']}}",

content: this.content,

client_id: this.client_id

}).then(function(res){

if (res.data.code === 200) {

Ca.content = '';

}

}).catch(function(err){

console.error(err)

})

},

mesList(){

axios.get("{{url('/api/mesList')}}",{params:{

from:"{{$_GET['name']}}",

to:"{{$_GET['to']}}",

client_id: Ca.client_id

}}).then(function(res){

if (res.data.code === 200) {

Ca.lists = res.data.list

}

}).catch(function(err){

console.error(err)

})

},

read(){

axios.put("{{url('/api/mesRead')}}",{params:{

from: "{{$_GET['name']}}",

to: "{{$_GET['to']}}",

}}).then(function(res){

console.log(res)

}).catch(function(err){

console.log(err)

})

}

}

})

复制代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GatewayWorker是一种基于事件驱动的高性能网络通信框架,可以用于实现长连接的应用,比如即时通讯、推送服务等。下面是一个简单的使用GatewayWorker实现数据传输的示例: 1. 安装GatewayWorker: ```bash composer require workerman/gateway-worker ``` 2. 创建一个GatewayWorker应用: ```php <?php use Workerman\Worker; use GatewayWorker\Gateway; // 创建一个GatewayWorker实例,监听端口为1234 $gateway = new Gateway("websocket://0.0.0.0:1234"); // 启动GatewayWorker Worker::runAll(); ``` 3. 编写客户端代码: ```html <!-- 客户端html页面 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>GatewayWorker Test</title> </head> <body> <input type="text" id="message" placeholder="请输入消息"> <button onclick="send()">发送</button> <ul id="messages"></ul> <script> var ws = new WebSocket("ws://localhost:1234"); ws.onmessage = function(event) { var li = document.createElement("li"); li.innerText = event.data; document.getElementById("messages").appendChild(li); }; function send() { var message = document.getElementById("message").value; ws.send(message); } </script> </body> </html> ``` 4. 编写服务端代码: ```php <?php use Workerman\Worker; use GatewayWorker\Gateway; // 创建一个GatewayWorker实例,监听端口为1234 $gateway = new Gateway("websocket://0.0.0.0:1234"); // 当客户端连接时触发 $gateway->onConnect = function($client_id) { echo "Client connected: $client_id\n"; }; // 当客户端发来消息时触发 $gateway->onMessage = function($client_id, $message) use ($gateway) { echo "Message received from client $client_id: $message\n"; // 将消息发送给所有客户端 $gateway->sendToAll("Message from $client_id: $message"); }; // 启动GatewayWorker Worker::runAll(); ``` 在浏览器中打开客户端页面,输入消息并点击“发送”按钮,就能将消息发送到服务端并在客户端页面上显示出来。服务端会将收到的消息广播给所有客户端。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值