Is it possible in dart to put a certain key infront of your Socket ip - dart

I have the following peer class
class Peer {
Peer({required this.count});
int count;
Future listen(String ip, int port) async {
ServerSocket ss = await ServerSocket.bind(ip, port);
ss.listen((client) {
print(client);
});
}
Future connect(String sstring) async {
final Socket s = await Socket.connect(
sstring.split(':')[0], int.parse(sstring.split(':')[1]));
await s.close();
}
}
and i was wondering if it was possible to put a certain key infront of my ip so it would listen on abc#127.0.0.1 instead of only 127.0.0.1

Related

Dart Web Request and Response as a Stream of data

I have been trying to setup an HTTP connection from a Dart client to a Dart Server using the HttpServer and HttpClient classes respectively.
I want to use this connection to transmit event updates to the client whenever the server feels necessary, so the connection needs to be continuous and the response needs to be sent in chunks, not buffered.
I tried this approach using two different server configurations (once with HttpServer, once with Shelf), but both times the response awaited closing and then the data was printed by the client.
Here is my server code:
var httpsServer = await io.HttpServer.bind("127.0.0.1", 4001);
httpsServer.listen((request) {
request.response.bufferOutput = false;
request.response.headers.add("Content-Type", "text/event-stream");
request.response.headers.add("Cache-Control", "no-cache");
request.response.headers.add("Connection", "keep-alive");
// asynchronously write "Hello" every 100 ms
Timer.periodic(Duration(milliseconds: 100), (Timer timer) {
try {
request.response.write("Hello\n");
} catch (_) {
timer.cancel();
}
});
await Future.delayed(Duration(seconds: 3));
request.response.close();
});
And another using shelf:
{
var handler = const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);
var server = await serve(handler, '127.0.0.1', 4000);
server.autoCompress = true;
}
FutureOr<Response> _echoRequest(Request request) {
Stream<List<int>> stream = Stream.periodic(Duration(milliseconds: 100), (int i) {
return utf8.encode("Hello\n");
}).take(10);
return Response.ok(stream);
}
However, on the client, I only receive the data once the connection has been closed:
HttpClient client = HttpClient()..badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
HttpClientRequest request = await client.postUrl(Uri.parse('https://---/'));
request.headers.add('Content-Type', 'text/event-stream');
HttpClientResponse response = await request.close();
// use startChunkConversion to convert the stream of bytes to a stream of strings
Stream<String> stream = response.transform(utf8.decoder).transform(const LineSplitter());
await for (String line in stream) {
print(line);
}
Am I doing something wrong or would I be better off with a different library / approach?

flutter socket.io client not working ~~~ helpme

I am making a chat app using flutter.
However, the socket connection does not work.
Port 80 is all connected locally, but sockets using aws are not connected.
I've tried both http and https, but no response. Help me!
Only the app does not connect, but the web connects.
The version of socket io client is 1.0.2, and the version of socket io is 2.3.0.
class _WebrtcState extends State<Webrtc> {
late final IO.Socket socket;
// late final SocketIO socketIO;
final _localRenderer = RTCVideoRenderer();
final _remoteRenderer = RTCVideoRenderer();
MediaStream? _localStream;
RTCPeerConnection? pc;
String check = "aafafasdfs";
#override
void initState() {
print('initState');
init();
super.initState();
}
Future init() async {
print('init');
await _localRenderer.initialize();
await _remoteRenderer.initialize();
await connectSocket();
await joinRoom();
}
Future connectSocket() async {
print('connectSocket');
socket = IO.io('http://********', IO.OptionBuilder().setTransports(['websocket']).build());
print(socket.opts);
socket.onConnect( (_){
print('connect');
setState(() {
check = "11111111111111111111ㅈ111";
});
});
socket.on('joined', (data) {
_sendOffer();
});
socket.on('offer', (data) async{
data = jsonDecode(data);
await _getOffer(RTCSessionDescription(data['sdp'], data['type']));
await _sendAnswer();
});
socket.on('answer', (data) {
data = jsonDecode(data);
_getAnswer(RTCSessionDescription(data['sdp'], data['type']));
});
socket.on('ice', (data) {
data = jsonDecode(data);
_getIce(RTCIceCandidate(data['candidate'], data['sdpMid'], data['sdpMLineIndex']));
});
}
}
To open a WebSocket connection, we need to create a new WebSocket using the special protocol ws in the URL:
final channel = WebSocketChannel.connect(
Uri.parse('wss://echo.websocket.org'),
);
There's also encrypted wss:// protocol. It's like HTTPS for WebSockets.
Please change the URL to something like the below form :
ws://********
wss://********

Riverpod StreamProvider access the stream

I am using socket_client_io and Riverpod. Socket client uses events for updates which I want to propagate in a StreamProvider.
What I currently have is the following. It gets the job done but... I would like to write directly to the stream within StreamProvider so I don't need to create an extra stream just to go from events to yield.
final downloadProgressProvider = StreamProvider.autoDispose<Progress>((ref) async* {
// open socketio
final Server host = ref.read(configProvider).talkServer;
final String jwt = ref.read(userProvider).jwt;
IO.Socket _socket = IO.io('${host.uri.toString()}/?token=$jwt', IO.OptionBuilder()
.setTransports(['websocket'])
.build()
);
StreamController<Progress> _stream = StreamController<Progress>();
ref.onDispose(() {
// close socketio
_stream.close();
_stream = null;
_socket.dispose();
_socket = null;
});
_socket.on('download-update', (message) {
print('download-update incoming');
_stream.add(Progress.fromJson(json.decode(message)))
});
await for (final value in _stream.stream) {
yield value;
}
});

dart io websocket done not called when client disconnects

I am trying to detect when a client has disconnected from the server. I thought that this was the correct way of doing it, but "someone disconnected" is never printed to the console.
import 'dart:io';
class VersusServer {
Future<void> run() async {
final PORT = 7171;
var server = await HttpServer.bind(InternetAddress.loopbackIPv4, PORT);
server.forEach(_handleRequest);
print('Server listening on port $PORT.');
}
void _handleRequest(HttpRequest request) async {
if (request.uri.path == '/ws') {
var socket = await WebSocketTransformer.upgrade(request);
print('someone connected');
// MARK: this is the part I am trying to listen to disconnect
socket.done.then((value) => print('someone disconnected'));
socket.listen((message) {
print(message);
});
}
}
}
Is there something wrong in my code?
Thanks in advance!

Cloud Dataflow - how does Dataflow do parallelism?

My question is, behind the scene, for element-wise Beam DoFn (ParDo), how does the Cloud Dataflow parallel workload? For example, in my ParDO, I send out one http request to an external server for one element. And I use 30 workers, each has 4vCPU.
Does that mean on each worker, there will be 4 threads at maximum?
Does that mean from each worker, only 4 http connections are necessary or can be established if I keep them alive to get the best performance?
How can I adjust the level of parallelism other than using more cores or more workers?
with my current setting (30*4vCPU worker), I can establish around 120 http connections on the http server. But both server and worker has very low resource usage. basically I want to make them work much harder by sending out more requests out per second. What should I do...
Code Snippet to illustrate my work:
public class NewCallServerDoFn extends DoFn<PreparedRequest,KV<PreparedRequest,String>> {
private static final Logger Logger = LoggerFactory.getLogger(ProcessReponseDoFn.class);
private static PoolingHttpClientConnectionManager _ConnManager = null;
private static CloseableHttpClient _HttpClient = null;
private static HttpRequestRetryHandler _RetryHandler = null;
private static String[] _MapServers = MapServerBatchBeamApplication.CONFIG.getString("mapserver.client.config.server_host").split(",");
#Setup
public void setupHttpClient(){
Logger.info("Setting up HttpClient");
//Question: the value of maxConnection below is actually 10, but with 30 worker machines, I can only see 115 TCP connections established on the server side. So this setting doesn't really take effect as I expected.....
int maxConnection = MapServerBatchBeamApplication.CONFIG.getInt("mapserver.client.config.max_connection");
int timeout = MapServerBatchBeamApplication.CONFIG.getInt("mapserver.client.config.timeout");
_ConnManager = new PoolingHttpClientConnectionManager();
for (String mapServer : _MapServers) {
HttpHost serverHost = new HttpHost(mapServer,80);
_ConnManager.setMaxPerRoute(new HttpRoute(serverHost),maxConnection);
}
// config timeout
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.setSocketTimeout(timeout).build();
// config retry
_RetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(
IOException exception,
int executionCount,
HttpContext context) {
Logger.info(exception.toString());
Logger.info("try request: " + executionCount);
if (executionCount >= 5) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
return true;
}
};
_HttpClient = HttpClients.custom()
.setConnectionManager(_ConnManager)
.setDefaultRequestConfig(requestConfig)
.setRetryHandler(_RetryHandler)
.build();
Logger.info("Setting up HttpClient is done.");
}
#Teardown
public void tearDown(){
Logger.info("Tearing down HttpClient and Connection Manager.");
try {
_HttpClient.close();
_ConnManager.close();
}catch (Exception e){
Logger.warn(e.toString());
}
Logger.info("HttpClient and Connection Manager have been teared down.");
}
#ProcessElement
public void processElement(ProcessContext c) {
PreparedRequest request = c.element();
if(request == null)
return;
String response="{\"my_error\":\"failed to get response from map server with retries\"}";
String chosenServer = _MapServers[request.getHardwareId() % _MapServers.length];
String parameter;
try {
parameter = URLEncoder.encode(request.getRequest(),"UTF-8");
} catch (UnsupportedEncodingException e) {
Logger.error(e.toString());
return;
}
StringBuilder sb = new StringBuilder().append(MapServerBatchBeamApplication.CONFIG.getString("mapserver.client.config.api_path"))
.append("?coordinates=")
.append(parameter);
HttpGet getRequest = new HttpGet(sb.toString());
HttpHost host = new HttpHost(chosenServer,80,"http");
CloseableHttpResponse httpRes;
try {
httpRes = _HttpClient.execute(host,getRequest);
HttpEntity entity = httpRes.getEntity();
if(entity != null){
try
{
response = EntityUtils.toString(entity);
}finally{
EntityUtils.consume(entity);
httpRes.close();
}
}
}catch(Exception e){
Logger.warn("failed by get response from map server with retries for " + request.getRequest());
}
c.output(KV.of(request, response));
}
}
Yes, based on this answer.
No, you can establish more connections. Based on my answer, you can use a async http client to have more concurrent requests. As this answer also describes, you need to collect the results from these asynchronous calls and output it synchronously in any #ProcessElement or #FinishBundle.
See 2.
Since your resource usage is low, it indicates that the worker spends most of its time waiting for a response. I think with the described approach above, you can utilize your resources far better and you can achieve the same performance with far less workers.

Resources