先上有问题的代码:

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";
    }
}


相关评论(0)
您是不是忘了说点什么?

友情提示:垃圾评论一律封号...

还没有评论,快来抢沙发吧!