laravel-swoole icon indicating copy to clipboard operation
laravel-swoole copied to clipboard

WebSocket client got redundant number in message event data

Open ft525 opened this issue 3 years ago • 18 comments

  1. Please provide your PHP and Swoole version. (php -v and php --ri swoole) PHP Version 7.3.16 swoole 4.5.7

  2. Please provide your Laravel/Lumen version. laravel v5.5.48

  3. Which release version of this package are you using? swooletw/laravel-swoole v2.6.68

  4. What did you do? If possible, provide a recipe for reproducing the error.

// Server
Websocket::on('connect', function ($websocket, Request $request) {
	// called while socket on connect
	$websocket->emit('message', 'Welcome ~');
});
// Client
var ws = new WebSocket("ws://example.com");
ws.onmessage = function (event) {
	console.log(event);
};
  1. What did you expect to see? The correct format of response. ex. json、array

  2. What did you see instead?

/*
There is a redundant number in event data.
Is it normal?
*/
MessageEvent {isTrusted: true, data: "0{"sid":"NWZkOWIxMWFiNjg3NQ==","upgrades":[],"pingInterval":25000,"pingTimeout":60000}", ...}
MessageEvent {isTrusted: true, data: "40", ...}
MessageEvent {isTrusted: true, data: "42["message","Welcome ~"]", ...}

ft525 avatar Dec 16 '20 07:12 ft525

Well, I never see this before 👀

Have you tried with newer versions of Laravel?

Arkanius avatar Dec 17 '20 23:12 Arkanius

Well, I never see this before 👀

Have you tried with newer versions of Laravel?

Not yet, but I'll try when I'm free.

ft525 avatar Dec 21 '20 08:12 ft525

Thanks for your help!

Arkanius avatar Dec 21 '20 15:12 Arkanius

Thanks for your help!

I tried, still the same. These are I installed version

PHP Version 7.3.12 Swoole Version 4.5.10 Laravel Version 8.20.1

swooletw/laravel-swoole v2.6.68

ft525 avatar Jan 05 '21 03:01 ft525

you should use a client with a socket.io implemention, socket.io-client, as the ws server is compatible with socket.io 2.x by default

solaz3 avatar Feb 04 '21 08:02 solaz3

you should use a client with a socket.io implemention, socket.io-client, as the ws server is compatible with socket.io 2.x by default

OK, I'll try it later.

ft525 avatar Feb 04 '21 13:02 ft525

you should use a client with a socket.io implemention, socket.io-client, as the ws server is compatible with socket.io 2.x by default

I tried and blocked by CORS policy. I don't know how to set swoole WebSocket CORS setting. : (

ft525 avatar Feb 17 '21 06:02 ft525

Try to run a nginx server in front of your swoole. Take a look at this exemple.

You should avoid use the header() funcion of php directly when using swoole because it's just ignored by swoole as mentioned here

Arkanius avatar Feb 17 '21 12:02 Arkanius

Are you using a socket.io client as said before?

Arkanius avatar Feb 17 '21 12:02 Arkanius

I tried all I can do. middleware、nginx、your example all failed. : (

ft525 avatar Feb 18 '21 09:02 ft525

I tried all I can do. middleware、nginx、your example all failed. : (

Hi, @ft525 there are several ways to resolve cors problems, you can either use a package called laravel-cors or add clips in nginx which is more effective, here is the full example:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
server {
    listen 80;
    server_name your.domain.com;
    root /path/to/laravel/public;
    index index.php;

    location = /index.php {
        # Ensure that there is no such file named "not_exists"
        # in your "public" directory.
        try_files /not_exists @swoole;
    }

    # any php files must not be accessed
    #location ~* \.php$ {
    #    return 404;
    #}
    location / {
        try_files $uri $uri/ @swoole;
    }

    location @swoole {
        # cors begin
        add_header Access-Control-Allow-Origin $http_origin always; 
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always;
        add_header Access-Control-Allow-Credentials true always;
        add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,x-auth-token always;
        add_header Access-Control-Max-Age 1728000 always;
 
        # preflight request return 204
        if ($request_method = OPTIONS) {
                return 204;
        }
        # end of cors

        set $suffix "";

        if ($uri = /index.php) {
            set $suffix ?$query_string;
        }

        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # IF https
        # proxy_set_header HTTPS "on";

        proxy_pass http://127.0.0.1:1215$suffix;
    }
}

solaz3 avatar Apr 06 '21 06:04 solaz3

Additional, here is a online socket.io client tool for debugging.

solaz3 avatar Apr 06 '21 07:04 solaz3

As @solaz3 said, you should inject the headers directly in your nginx before getting them in your code

Arkanius avatar Apr 06 '21 15:04 Arkanius

OK, I tried. It does work. But I can't receive message event and custom event. I just saw "Connected." msg.

// server
Websocket::on('connect', function ($websocket, Request $request) {
	// called while socket on connect
	$websocket->emit('hello', 'Hello ~');
	$websocket->emit('message', 'Welcome ~');
});
/*
	client (socket.io v2.4)

	// Docs
	https://socket.io/docs/v2/client-api/#socket-on-eventName-callback
*/
socket.on("connect", function () {
	console.log("Connected.");
});

socket.on("message", function (msg) {
	console.log("On message.", msg);
});

socket.on("hello", function (arg) {
	console.log("On hello.", arg);
});

ft525 avatar Apr 14 '21 06:04 ft525

add a disconnect event to socket to check if disconnected immediately after connected. Or use socket.io client tool which is simple and powerful.

solaz3 avatar Apr 14 '21 14:04 solaz3

It is still connected till I disconnect it. I'll try socket.io client tool when I am free. thx~

ft525 avatar Apr 15 '21 01:04 ft525

I found the problem. When I added the option (see below), It did work correctly Summary 1. It should use socket.io client v2.x 2. Connection options should add "transports" setting

// client
socket = new io("ws://xxx", {
	transports: ["websocket"],	// default is ["polling", "websocket"]
});

ft525 avatar Apr 19 '21 09:04 ft525

It should use socket.io client v2.x, otherwise fail. You can see the message prompt

// client
socket.on('connect_error', (error: string) => {
  console.error(error);
});

TORYOI avatar Mar 17 '23 03:03 TORYOI