Comments (17)
Any progress on this? π
from web_socket_channel.
I think that I found not ideal but technically correct solution:
final httpClient = HttpClient();
httpClient.connectionTimeout = Duration(seconds: 20);
final webSocket = await WebSocket.connect(
'some url',
customClient: httpClient,
);
final channel = IOWebSocketChannel(webSocket);
from web_socket_channel.
What i was doing is create a native socket and wrap it in IOWebSocketChannel
Like this
WebSocket.connect(_SERVER_ADDRESS)
.timeout(Duration(seconds: 20))
.then((ws) {
try {
_channel = new IOWebSocketChannel(ws);
} catch (e) {
print(
'Error happened when opening a new websocket connection. ${e.toString()}');
}
from web_socket_channel.
@ziedReg I'm probably too late, but the issue here is that you are using HtmlWebSocketChannel (for web) while @kavinda1995 is using IOWebSocketChannel (for mobile). As noted, the WebSocket class in use is from the dart:io package, which cannot be used for web development. The two websocket implementations are not interchangeable.
from web_socket_channel.
@sm2017 is correct. This can lead to resource leaks. The timeout passed to the WebSocket
is for the communication Stream
, not the establishment of the WebSocket
.
It seems to me that a viable solution could be to pass a connectionTimeout
parameter to the WebSocket
constructor which would be passed on to the HttpClient
when establishing a connection. This could also trickle up to IOWebSocketChannel.connect
making establishing web sockets much easier/safer. Unless there is a reason unbeknown to me why this is should not be.
Currently, I believe the safest way to handle timeouts when establishing a web socket in Dart is to use an HttpClient
and manually upgrade to a WebSocket
. Then you can create the IOWebSocketChannel
with the WebSocket
.
final r = Random();
final key = base64.encode(List<int>.generate(8, (_) => r.nextInt(255)));
final client = HttpClient();
client
.getUrl(Uri.parse(SERVER_ADDRESS))
.timeout(Duration(seconds: 20))
.then((request) {
request.headers.add('Connection', 'upgrade');
request.headers.add('Upgrade', 'websocket');
request.headers.add('sec-websocket-version', '13');
request.headers.add('sec-websocket-key', key);
request.close().then((response) {
response.detachSocket().then((socket) {
final webSocket = WebSocket.fromUpgradedSocket(socket, serverSide: false);
_channel = IOWebSocketChannel(webSocket);
});
});
}).catchError((error) {
// handle error
return null;
});
from web_socket_channel.
What i was doing is create a native socket and wrap it in IOWebSocketChannel
Like this
WebSocket.connect(_SERVER_ADDRESS) .timeout(Duration(seconds: 20)) .then((ws) { try { _channel = new IOWebSocketChannel(ws); } catch (e) { print( 'Error happened when opening a new websocket connection. ${e.toString()}'); }
@kavinda1995 is your approach safe?
Consider the following scenario:
1- By running WebSocket.connect
a web socket connection will be established but due to network issues, it can be established after 30 seconds
2- timeout(Duration(seconds: 20))
will completeError
the feature with TimeoutException
after 20 seconds
3- We have a reconnect logic in our code in the catch
and do same thing for connection
4- By running WebSocket.connect
again, a new web socket connection will be established without timeout
5- after 30 seconds, the first connection is established, So we have 2 web socked connection, and there is no way to close the first
from web_socket_channel.
@ycherniavskyi This is a good solution. I would also suggest setting httpClient.idleTimeout
and/or webSocket.pingInterval
according to your needs.
from web_socket_channel.
@kavinda1995 I got an error. The WebSocket that comes from connect is from flutter/bin/cache/pkg/sky_engine/lib/_http/websocket.dart
while the IOWebSocketChannel requires a WebSocket from flutter/bin/cache/pkg/sky_engine/lib/html/html_dart2js.dart
.
from web_socket_channel.
@zeidReg - No. You must import WebSocket from dart:io. Not from any other package
from web_socket_channel.
@kavinda1995 I don't really get it. I imported it from dart:io but when i press Ctrl + click on the class name i go to the file flutter/bin/cache/pkg/sky_engine/lib/_http/websocket.dart
from web_socket_channel.
@ziedReg please provide your code snippet here. So we can elaborate π
from web_socket_channel.
These are the imports
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:web_socket_channel/html.dart';
import 'package:my_project/constants/variables.dart';
import 'package:web_socket_channel/io.dart';
this is the method where i connect to the socket
void fetchImages() {
if (channel == null) {
// copying your code
WebSocket.connect("ws://"+settings.host+":"+settings.port.toString()).timeout(Duration(seconds: 5)).then((ws) {
try {
channel = new HtmlWebSocketChannel(ws); // there is an error at "ws"
} catch (e) {
print('Error happened when opening a new websocket connection. ${e.toString()}');
}
});
// what i'm working with right now
channel = HtmlWebSocketChannel.connect("ws://"+settings.host+":"+settings.port.toString());
}
channel.stream.listen((message) async{
bytes = base64Decode(message);
image = Image.memory(bytes);
await precacheImage(image.image, context);
setState(() {});
});
}
The error is : The argument type 'WebSocket (where WebSocket is defined in ~/flutter/bin/cache/pkg/sky_engine/lib/_http/websocket.dart)' can't be assigned to the parameter type 'WebSocket (where WebSocket is defined in ~/flutter/bin/cache/pkg/sky_engine/lib/html/html_dart2js.dart)'. (argument_type_not_assignable at [my_project] lib/views/control/control.dart:44)
I am using HtmlWebSocketChannel
because i'm working on web but i tried IOWebSocketChannel
and got the same error
from web_socket_channel.
Oh π. Couldn't see any wrong in this
from web_socket_channel.
So there really isn't a good way to do this, particularly since the dart:html package only offers a constructor that doesn't return a future
from web_socket_channel.
Thanks, works great! @theLee3 Any solution for Web though?
from web_socket_channel.
@julien100000 For the web, we can simply check the status of the WebSocket
after the desired timeout period, and if the connection has not been established, close the socket and handle the timeout according to your needs.
// WebSocket class from `html` library
final webSocket = WebSocket(SERVER_ADDRESS);
Future.delayed(Duration(seconds: 20), () {
if (webSocket.readyState == WebSocket.CONNECTING) {
webSocket.close();
// handle the timeout here
}
});
_channel = HtmlWebSocketChannel(webSocket);
from web_socket_channel.
I think that I found not ideal but technically correct solution:
final httpClient = HttpClient(); httpClient.connectionTimeout = Duration(seconds: 20); final webSocket = await WebSocket.connect( 'some url', customClient: httpClient, ); final channel = IOWebSocketChannel(webSocket);
This is a viable workaround, but dart:io
is not allowed in web
from web_socket_channel.
Related Issues (20)
- Build Failed Because of EventStream error HOT 2
- Flutter build web failing due to EventStreamProviders HOT 6
- WebSocketException: Connection not upgraded to websocket HOT 6
- How to get readyState from WebSocketChannel?
- web_socket_channel ^2.4.2δΎηΆζ²‘ζζ―ζweb0.3.0 HOT 1
- Socket connection for self signed certificate
- While I can introduce web_socket_channel into dart, iOS won't be able to call this package
- Web version websocket doesn't work, but ios does HOT 4
- websocket is not connecting
- Add feature HOT 1
- Auto invoke onDown method to close websocket. HOT 1
- Specifying 'protocols' (Sec-WebSocket-Protocol header) causes connection to close.
- HTML: When the WebSocket is in a 'pending' state, calling channel.sink.close does not work. HOT 2
- Masking is not cryptographically secure HOT 1
- I tried to connect with localhost 8081 port but its connect with diffrent port HOT 2
- FormatException: Unexpected character
- Simplify the web_socket_channel implementation HOT 5
- Message received in wrong order
- Support MSGPACK HOT 1
- Any problems with WebSocketChannel.connect under iOS 17.5 beta (or earlier)? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from web_socket_channel.