Closed nicolasvahidzein closed 2 years ago
also should we use .ws or .wss to connect?
Hello, if you have the security context on your server use wss
, otherwise - use ws
. The same thing why http
and https
are different.
Thank you for this package that was recommended to me but is it compatible with laravel echo and laravel websockets on my own server and using a pusher replacement service?
I don't have a key to put in the options.
If you please have a sample config to use for this setup i would be very grateful.
@nicolasvahidzein I've read the issue and added a feature to add custom path to PusherChannelOptions
if you don't have key
, key
is now nullable. Set your endpoint path
and set key
to null.
Important
: Also, I've updated API reference in version 0.2.8
just today (which is an inline code reference) on pub.dev. Link to API reference of PusherChannelOptions
.
So this may be your case:
// If your server is `wss`
const withPath = PusherChannelOptions.wss(
host: 'example.com',
path: '/CUSTOM_PATH',
port: 443,
key: null,
protocol: 7);
// If your server is `ws`
const withPath = PusherChannelOptions.ws(
host: 'example.com',
path: '/CUSTOM_PATH',
port: 12,
key: null,
protocol: 7);
Pay an attention to /CUSTOM_PATH
- it's you endpoint to web socket connection (alternative to /app/[KEY]). If you do not have path set - path:'/'
For the other samples, please check the test file (group with name "Pusher Channel options uri must be convinient").
I've described and tested most of the use-cases
@nicolasvahidzein By the way, my partner developer used own Laravel server as host. So, I think yes - if your laravel library supports Pusher protocol - it's okay.
Specifically, in this client library I used web_socket_channel
for WebSocketChannelConnectionDelegate
under the hood.
@nicolasvahidzein
Additionally, here is a link to API reference of the default constructor of PusherChannelOptions
. It now has detailed description of the parameters.
If these comments helped you - I will close the issue. Please, inform me about your progress.
Hello @mcfugger I upgraded to 0.3.0 and i'm getting a message saying that:
'PusherChannelOptions' is deprecated and shouldn't be used. The class was renamed to [PusherChannelsOptions].. Try replacing the use of the deprecated member with the replacement.
I wrote it like this:
PusherChannelOptions options = PusherChannelOptions(
scheme: 'ws',
key: null,
host: websocketsDomain,
path: websocketsAuthEndpointRelativeUrl,
port: websocketsPort,
protocol: 7,
version: '7.0.3',
cluster: websocketsCluster,
);
Please disregard previous comment, i had missed the added "s" in the variable name.
Will test right now.
@nicolasvahidzein
Look, you should read API reference. path
is actually not the authentication endpoint, it is endpoint to your connection.
PusherChannelsOptions
take those parameters to generate a url for connection.
Typically, pusher channels urls look like this:
[scheme]://[host]:[port]/app/[key]
If you provide cluster, the generated url will be like:
[scheme]://ws-[cluster].[host]:[port]/app/[key]
But you said that you don't have key
, so I added feature to set custom path, so if you provide path
, your url will be generated like this:
[scheme]://ws-[cluster_name].[host]:[port][path]
.
Note:
There is no /
(slash) by default in front of the path - you should add it when you provide path
Like this:
...
path: /[YOUR_PATH]
...
How to know what url is generated by PusherChannelsOptions
?
// Print it
print(options.uri);
Or take a look at test file (group with name "Pusher Channel options uri must be convinient"). There are a lot of samples compared with its expected values. For example (from test file):
const withPath = PusherChannelsOptions(
scheme: 'ws',
host: 'example.com',
path: '/CUSTOM_PATH',
port: 12,
key: null,
protocol: 7);
expect(
withPath.uri,
Uri.parse(
'ws://example.com:12/CUSTOM_PATH?client=dart&version=$kDartPusherChannelsLibraryVersion&protocol=7'));
path
is not an endpoint for authentication - it's alternative if you don't have key
.
@nicolasvahidzein Please, inform me about your progress in this thread. We will make it through :-)
path
is not an endpoint for authentication - it's alternative if you don't havekey
.
i'm confused, so what do i put in path then? I'll paste here all my values and you can tell me what i should use.
@nicolasvahidzein Okay, replace your original host with example.com to keep it safe here. If you provide your full link, I will tell
const String websocketsAppIdDev = 'RTYG-4852-EFTG-1234'; const String websocketsDomainDev = '192.168.4.8'; const String websocketsAuthEndpointDomainDev = 'http://192.168.4.8:4521'; const String websocketsAuthEndpointRelativeUrlDev = '/broadcasting/auth'; const int websocketsPortDev = 3009; const String websocketsClusterDev = 'mt1'; const bool websocketsEncryptedDev = false;
PusherChannelsOptions options = PusherChannelsOptions(
scheme: 'ws',
key: null,
host: websocketsDomainDev,
path: websocketsAuthEndpointRelativeUrlDev,
port: websocketsPortDev,
protocol: 7,
version: '7.0.3',
cluster: websocketsClusterDev,
);
PusherChannelsClient pusher = PusherChannelsClient.websocket(
reconnectTries: 3,
options: options,
onConnectionErrorHandle: (error, trace, refresh) {
print('websocket error: $error');
},
);
//TURNED INTO A CLASS VARIABLE
//Channel? channel;
//TURNED INTO A CLASS VARIABLE
//StreamSubscription? eventSubscription;
pusher.onConnectionEstablished.listen((_) async {
//connect to a private channel
channel ??= pusher.privateChannel(
'user.${myUserId!}',
// This is a default authorization delegate
// to authorize to the channels
// You may implement your own authorization delegate
// implementing [AuthorizationDelegate] interface
// Use 'http' or 'https' scheme
TokenAuthorizationDelegate(
authorizationEndpoint: Uri.parse(websocketsAuthEndpointDomain + websocketsAuthEndpointRelativeUrl),
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
)
);
await eventSubscription?.cancel();
// Ensure you bind to the channel before subscribing, otherwise - you will miss some events
eventSubscription = channel?.bind('UserStatusChange').listen((event) {
//listen for events form the channel here
print(event);
});
channel!.subscribe();
});
//connect the service
pusher.connect();
And if i replace the values to make it easy to read:
PusherChannelsOptions options = PusherChannelsOptions(
scheme: 'ws',
key: null,
host: '192.168.4.8',
path: '/broadcasting/auth',
port: 3009,
protocol: 7,
version: '7.0.3',
cluster: 'mt1',
);
What is RTYG-4852-EFTG-1234
?
App ID set in laravel websockets. Not sure if it's useful.
To make it clear, are you sure you using Pusher protocol?
Yes sir. This is how i was connecting using laravel echo and laravel pusher flutter packages:
PusherOptions options = PusherOptions(
host: websocketsDomain,
port: websocketsPort,
cluster: websocketsCluster,
encrypted: websocketsEncrypted,
auth: PusherAuth(
websocketsAuthEndpointDomain + websocketsAuthEndpointRelativeUrl,
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
),
);
LaravelFlutterPusher pusher = LaravelFlutterPusher(
websocketsAppId,
options,
enableLogging: true,
);
_echo = Echo(
broadcaster: EchoBroadcasterType.Pusher,
client: pusher,
);
pusher.connect(onConnectionStateChange: (ConnectionStateChange event) {
print('event:');
print(event);
print(event.currentState);
if (event.currentState == 'CONNECTED') {
_appStore!.setEcho(_echo);
_appStore!.setWebsocketConnection(true);
_appStore!.incrementWebsocketConnectionAttempt();
} else if (event.currentState == 'DISCONNECTED') {
_appStore!.setWebsocketConnection(false);
}
}).onError((error, stackTrace) {
print('websocket error: $error');
});
//connect to the private channel
//you can piggy back channel listeners if you are adding more
_echo!.private('user.${myUserId!}').listen('UserStatusChange', (event) {
print(event);
});
Okay, try this (removed the cluster) (removed the version because it's set as default with the version of the library)
PusherChannelsOptions options = PusherChannelsOptions( scheme: 'ws', path: '', host: '192.168.4.8', port: 3009, protocol: 7, );
ok doing it now. This below looks right to you? The URI?
channel ??= pusher.privateChannel(
'user.${myUserId!}',
TokenAuthorizationDelegate(
authorizationEndpoint: Uri.parse('http://192.168.4.8:4521/broadcasting/auth'),
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
)
);
Okay, try this (removed the cluster) (removed the version because it's set as default with the version of the library)
And set path to ''
PusherChannelsOptions options = PusherChannelsOptions(
scheme: 'ws',
path: '',
key:null,
host: '192.168.4.8',
port: 3009,
protocol: 7,
);
So this library was made accoring to the client API documentation.
Did you test your server in browser?
If yes, then what url you used to test your web socket server?
Typically, they look like this:
ws://ws-ap1.pusher.com:80/app/APP_KEY?client=js&version=7.0.3&protocol=5
What yours looks like?
websocket error: WebSocketChannelException: WebSocketChannelException: WebSocketException: Connection to 'http://192.168.2.5:3009?client=dart&version=0.2.9&protocol=7#' was not upgraded to websocket
laravel websockets you connect to the server directly and authentify using the domain and authentication relative path.
there is no ws link involved.
laravel websockets you connect to the server directly and authentify using the domain and authentication relative path.
there is no ws link involved.
I guess, I know what's the case. I think it's because of the query parameters. Let me fix it in 10 minutes. I will add option to omit them.
ok. But i'm curious, others are using your package as is with laravel websockets on a custom server so how are they doing it? Your partner is achieving this how, do you know?
we also need to add the auth endpoints too i think.
ok doing it now. This below looks right to you? The URI?
channel ??= pusher.privateChannel( 'user.${myUserId!}', TokenAuthorizationDelegate( authorizationEndpoint: Uri.parse('http://192.168.4.8:4521/broadcasting/auth'), headers: { 'Authorization': 'Bearer ' + accessToken, 'Content-Type': 'application/json', 'Accept': 'application/json' } ) );
Here is where you can provide auth endpoint. This feature was added in very first versions :)
ok. But i'm curious, others are using your package as is with laravel websockets on a custom server so how are they doing it? Your partner is achieving this how, do you know?
See the closed issues of this library, the folks may help you with that, I will ask my teammate about it too
The 0.3.1
is live now.
If you add shouldSupplyQueryMetaData: false
. It will omit query parameters. Try it please.
const options = PusherChannelsOptions(
scheme: 'ws',
path: '',
key:null,
host: '192.168.4.8',
port: 3009,
protocol: 7,
shouldSupplyQueryMetaData: false);
@nicolasvahidzein Test the new version with as described above, please.
The
0.3.1
is live now.If you add
shouldSupplyQueryMetaData: false
. It will omit query parameters. Try it please.const options = PusherChannelsOptions( scheme: 'ws', path: '', key:null, host: '192.168.4.8', port: 3009, protocol: 7, shouldSupplyQueryMetaData: false);
@nicolasvahidzein Try this
@nicolasvahidzein I will be waiting for the updates in your progress. Keep the thread up-to-date, we will go through it.
ok testing now
WebSocketException: Connection to 'http://192.168.2.5:3009#' was not upgraded to websocket
it added a pound symbol but i think we are close.
@nicolasvahidzein No, pound symbol is part of an exception. You must now check if your host server was upgraded to web sockets or try different port. When I had this exception with my project on test server - I tried always port 12.
The issue on server side.
I am not seeing any connection attempt on the server, maybe i am looking in the wrong place. Is there another place besides my laravel websocket process i can check?
Try to upgrade your server to ws or wss. What do you use nginx or Apache?
I am not a server-side developer. These answers might be helpful: https://stackoverflow.com/a/72135334/12177707
I would recommend also those things:
i'm using port 3009 for sure. No doubt about that as it's working with laravel_flutter_pusher.
laravel_flutter_pusher based on native plugins, so my guess is that they make connections over http/https schemes. This library tries to connect using ws/wss schemes (web_socket_channel) and your server does not allow connection because the server was not upgraded to web sockets (ws/wss) as the exception claims.
yikes. This is a problem. I wonder how Yassine did it. I will wait for him to reply to my email and ask him and revert back here.
Thanks a lot @mcfugger i'll update you here. All your hard work and wonderful plugin are appreciated.
Thank you very much! You are welcome. I will keep the issue open unless assumption is confirmed. It might be helpful: https://stackoverflow.com/a/72135334/12177707
Will be waiting for updates here.
I should mention that i am using an older version of laravel websocket v1.1 on Laravel v 5.8. Not sure if that is the issue.
....
GET / HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: SOME_KEY
....
Origin: http://example.com
@nicolasvahidzein Do you know where to find these configs on a server?
I think the line makes sense:
Upgrade: websocket
@nicolasvahidzein And check this informative answer too: https://stackoverflow.com/questions/66597039/laravel-websocket-wont-connect-on-production
also i think i am using pusher v5 since my version of laravel websockets is so old.
I spoke to one of your users Yassine who was very helpful. I guess i need to upgrade my packages (websockets and pusher) and then implement your package. No choice. My versions are too old.
@nicolasvahidzein It's a power of community :) Tell me when you make it with the new version of Laravel - then I will close the issue
Thank you for this package that was recommended to me but is it compatible with laravel echo and laravel websockets on my own server and using a pusher replacement service?
I don't have a key to put in the options.
If you please have a sample config to use for this setup i would be very grateful.