Skip to content
This repository has been archived by the owner on Sep 10, 2024. It is now read-only.

WebSocket client got redundant number in message event data #459

Open
ft525 opened this issue Dec 16, 2020 · 18 comments
Open

WebSocket client got redundant number in message event data #459

ft525 opened this issue Dec 16, 2020 · 18 comments

Comments

@ft525
Copy link

ft525 commented Dec 16, 2020

  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 ~"]", ...}
@Arkanius
Copy link
Contributor

Well, I never see this before 👀

Have you tried with newer versions of Laravel?

@ft525
Copy link
Author

ft525 commented Dec 21, 2020

Well, I never see this before 👀

Have you tried with newer versions of Laravel?

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

@Arkanius
Copy link
Contributor

Thanks for your help!

@ft525
Copy link
Author

ft525 commented Jan 5, 2021

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

@solaz3
Copy link

solaz3 commented Feb 4, 2021

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

@ft525
Copy link
Author

ft525 commented Feb 4, 2021

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
Copy link
Author

ft525 commented Feb 17, 2021

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.
: (

@Arkanius
Copy link
Contributor

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
Copy link
Contributor

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

@ft525
Copy link
Author

ft525 commented Feb 18, 2021

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

@solaz3
Copy link

solaz3 commented Apr 6, 2021

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
Copy link

solaz3 commented Apr 6, 2021

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

@Arkanius
Copy link
Contributor

Arkanius commented Apr 6, 2021

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

@ft525
Copy link
Author

ft525 commented Apr 14, 2021

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

@solaz3
Copy link

solaz3 commented Apr 14, 2021

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

@ft525
Copy link
Author

ft525 commented Apr 15, 2021

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

@ft525
Copy link
Author

ft525 commented Apr 19, 2021

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

@TORYOI
Copy link

TORYOI commented Mar 17, 2023

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants