php怎么用websocket(76phpEvent库操作socket注意事项)

1、无法执行多次回调
  • 再次执行上一篇的案例

php怎么用websocket(76phpEvent库操作socket注意事项)(1)

此种情况有点类似定时器,隔n秒执行一次的效果。如果要反复执行监听。需要加上"Event::PERSIST"

  • 修改Event构造方法的参数

$eventsocket = new Event($eventBase,$resource,Event::READ|Event::PERSIST,'accept');

  • 再次执行

php怎么用websocket(76phpEvent库操作socket注意事项)(2)

2、嵌套问题

这里嵌套是指在回调方法里面,新增加"监听"。比如之前案例中,在回调方法"accept",新增加可读or可写的监听

2.1、问题案例

在接收到新的socket链接时,针对该socket链接,监听其read操作

  • 源码

<?php

/**

* Copyright (C) Iamasb

* @project : 3、workerman相关知识点

* @explain : Event操作socket注意事项

* @filename : 40、Event操作socket注意事项.php

* @author : xiaobei 2801616735@qq.com

*/

// 创建tcp

if (!($resource = socket_create(AF_INET,SOCK_STREAM,SOL_TCP))) {

echo "socket create is error";

exit();

}

// 设置端口复用

if (!socket_set_option($resource, SOL_SOCKET, SO_REUSEADDR, 1)) {

echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL;

exit;

}

// 绑定当前主机和端口

if (!socket_bind($resource,'0.0.0.0','1234')) {

echo "socket bind is error";

exit();

}

// 启动监听

if (!socket_listen($resource)) {

echo "socket listen is error";

exit();

}

$eventBase = new EventBase();

$eventSocket = new Event($eventBase,$resource,Event::READ,'accept');

$eventSocket->add();

$eventBase->loop();

function accept($socket)

{

global $eventBase;

$client = socket_accept($socket);

socket_getpeername($client,$address,$port);

echo "new client->",$address,':',$port,PHP_EOL;

// 对新连接进行监听"read"

$eventSocket = new Event($eventBase,$client,Event::READ|Event::PERSIST,'read',$client);

if (!$eventSocket || !$eventSocket->add()) {

echo "error",PHP_EOL;

}

}

function read($socket)

{

$string = socket_read($socket,1024);

echo "receive from client->",trim($string),PHP_EOL;

socket_close($socket);

}

  • 执行结果

php怎么用websocket(76phpEvent库操作socket注意事项)(3)

php怎么用websocket(76phpEvent库操作socket注意事项)(4)

  • 结果分析

首先是设置read监听不起作用,其次是整个服务都挂掉了。为什么?

答: 从accept函数中得知,新创建了一个event实例化对象,然后加入监听中。但是但离开accept函数后,根据变量的作用域,就被系统收回了。因此不起作用

2.2、修改方案

通过引入全局变量,保存变量。从而延长变量的生命周期

  • 修改后的源码

<?php

/**

* Copyright (C) Iamasb

* @project : 3、workerman相关知识点

* @explain : Event操作socket

* @filename : 39、Event操作socket.php

* @author : xiaobei 2801616735@qq.com

*/

// 创建tcp

if (!($resource = socket_create(AF_INET,SOCK_STREAM,SOL_TCP))) {

echo "socket create is error";

exit();

}

// 设置端口复用

if (!socket_set_option($resource, SOL_SOCKET, SO_REUSEADDR, 1)) {

echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL;

exit;

}

// 绑定当前主机和端口

if (!socket_bind($resource,'0.0.0.0','1234')) {

echo "socket bind is error";

exit();

}

// 启动监听

if (!socket_listen($resource)) {

echo "socket listen is error";

exit();

}

$GLOBALS['event'] = array();

$GLOBALS['eventBase'] = new EventBase();

$eventSocket = new Event($eventBase,$resource,Event::READ|Event::PERSIST,'accept');

$eventSocket->add();

$GLOBALS['event'][(int)$resource] = $eventSocket;

$eventBase->loop();

function accept($socket)

{

echo "accept->",PHP_EOL;

$client = socket_accept($socket);

socket_getpeername($client,$address,$port);

echo "new client->",$address,':',$port,PHP_EOL;

$eventSocket = new Event($GLOBALS['eventBase'],$client,Event::READ|Event::PERSIST,'read',$client);

if (!$eventSocket || !$eventSocket->add()) {

echo "error",PHP_EOL;

}

$GLOBALS['event'][(int)$client] = $eventSocket;

return true;

}

function read($socket)

{

$string = socket_read($socket,1024);

echo "receive from client->",trim($string),PHP_EOL;

$eventSocket = new Event($GLOBALS['eventBase'],$socket,Event::WRITE|Event::PERSIST,'write',$socket);

if (!$eventSocket || !$eventSocket->add()) {

echo "error",PHP_EOL;

}

$GLOBALS['event'][(int)$socket] = $eventSocket;

}

function write($socket)

{

echo "todo->Write",PHP_EOL;

$string = "hello\n";

socket_write($socket,$string,strlen($string));

socket_close($socket);

$GLOBALS['event'][(int)$socket]->del();

unset($GLOBALS['event'][(int)$socket]);

}

  • 执行结果

php怎么用websocket(76phpEvent库操作socket注意事项)(5)

php怎么用websocket(76phpEvent库操作socket注意事项)(6)

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页