先上有问题的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class Server extends \swoole_websocket_server { public function __construct( $ip , $port ) { parent::__construct( $ip , $port ); $this ->init(); } protected function init() { $this ->on( 'open' , [ $this , '__open' ]); $this ->on( 'message' , [ $this , '__message' ]); $this ->on( 'close' , [ $this , '__close' ]); } protected function __open( $server , $request ) { echo "server: handshake success with fd{$request->fd}\n" ; } protected function __message( $server , $frame ) { echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n" ; $this ->push( $frame ->fd, "this is server" ); } protected function __close( $server , $fd ) { echo "client {$fd} closed\n" ; } } |
运行时候,onclose那一行报错,而open和message没毛病。
我上github提了issue,后来韩天峰大神回答了原因。
请所有事件回到设置为public
虽然另外两个事件回调设置成功了,但是这只是绕开了swoole_websocekt_server::on方法的检测,在回调这些函数时仍然可能遇到作用域的问题。
__close设置未成功是因为需要调用swoole_server_port::on方法将回调函数设置到监听端口上,这个类和swoole_websocekt_server没有任何继承关系。
下面给出两种解决方法。
方法一
将所有方法改为public,妥妥的,最方便。但是有强迫症患者,可能不舒服。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class Server extends \swoole_websocket_server { public function __construct( $ip , $port ) { parent::__construct( $ip , $port ); $this ->init(); } protected function init() { $this ->on( 'open' , [ $this , '__open' ]); $this ->on( 'message' , [ $this , '__message' ]); $this ->on( 'close' , [ $this , '__close' ]); } public function __open( $server , $request ) { echo "server: handshake success with fd{$request->fd}\n" ; } public function __message( $server , $frame ) { echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n" ; $this ->push( $frame ->fd, "this is server" ); } public function __close( $server , $fd ) { echo "client {$fd} closed\n" ; } } |
方法二
通过闭包,在闭包里调用方法。性能上多一次方法调用,可能略差,但是强迫症患者喜欢啊!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | class Server extends \swoole_websocket_server { public function __construct( $ip , $port ) { parent::__construct( $ip , $port ); $this ->init(); } protected function init() { $this ->on( 'open' , function ( $server , $request ){ $this ->__open( $server , $request ); }); $this ->on( 'message' , function ( $server , $frame ){ $this ->__message( $server , $frame ); }); $this ->on( 'close' , function ( $server , $fd ){ $this ->__close( $server , $fd ); }); } protected function __open( $server , $request ) { echo "server: handshake success with fd{$request->fd}\n" ; } protected function __message( $server , $frame ) { echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n" ; $this ->push( $frame ->fd, "this is server" ); } protected function __close( $server , $fd ) { echo "client {$fd} closed\n" ; } } |
友情提示:垃圾评论一律封号...