flutter socket.io client not working ~~~ helpme - ios

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://********

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?

How to read file from HTTPRequest on a dart:io server

I am trying to create a server to run locally for my application to upload some files while debugging. It is very simple and the full source code is:
import 'dart:io';
void main(List<String> arguments) async {
const port = 8080;
final server = await HttpServer.bind(InternetAddress.anyIPv4, port);
server.listen((request) async {
if (request.uri.path != '/save_screenshot' || request.method != 'POST') {
request.response.statusCode = 404;
request.response.close();
return;
}
// TODO: read the file
request.response.statusCode = 200;
request.response.close();
});
print('screenshot server listening on $port.');
}
At the code there is a TODO comment, where I would like to read the file from the HTTPRequest, I googled a bit and could not find a example to copy. Does anyone know how to read the file from the HTTPRequest?
Here is how it is being sent (on the client side):
final url = 'http://<local_ip_address>:8080/save_screenshot';
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(
http.MultipartFile.fromBytes(
'file',
screenshot.bytes,
filename: 'screenshot.png',
),
);
await request.send();
I found out how to read the file from the HTTPRequest. But for it to work it is necessary to install a package called mime.
Then replace the TODO comment in the question with:
final boundary = request.headers.contentType!.parameters['boundary']!;
final mimeTransformer = MimeMultipartTransformer(boundary);
final parts = request.cast<List<int>>().transform(mimeTransformer);
await for (final part in parts) {
final file = File('uploaded_files/0.png');
await part.pipe(file.openWrite());
}
I made a gist with the working server: https://gist.github.com/lslv1243/1036364b10c6578d969cb4ed2d7eba42
NOTE: on the gist I changed the path from /save_screenshot to /screenshot

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!

Is it possible to create a tcp client with electron

Is it possible to create a tcp client with electron?
Or can we access the chrome socket api with does that?
https://developer.chrome.com/apps/sockets_tcp
You can use the Node net API in Electron to implement a TCP client.
Try this sample code (don't forget to change IP address) with a little socket server as SocketTest java application for example (HERE).
At the connection, you should see a "World!" string on server side. Try to send this message from server:
{
"nom":"Xplorer",
"prenom":"Yann"
}
And you should see Hello Yann! in your electron console.
'use strict';
const electron = require('electron');
const path = require('path');
const url = require('url');
const net = require('net');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow;
var socketClient
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600,backgroundColor:'#FFFFFF', frame:false})
// and load the index.html of the app.
mainWindow.loadURL(url.format({
pathname: path.join(__dirname+'/html/', 'main.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
//mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
/* Instance socket on create window */
console.log('Try to connect');
socketClient = net.connect({host:'192.16.122.3', port:9042}, () => {
// 'connect' listener
console.log('connected to server!');
socketClient.write('world!\r\n');
});
socketClient.on('data', (data) => {
console.log(data.toString());
var person = JSON.parse(data);
console.log('Hello '+person.prenom+"!");
});
socketClient.on('end', () => {
console.log('disconnected from server');
});
//mainWindow.openDevTools();
}
app.on('before-quit',function(){
socketClient.end();
})
see you.
You can use the Node net API in Electron to implement a TCP client.
It's easy to just test if the chrome API is present. If not I use the node API. So that I have the same code base for my Chrome App and my Electron App.
The 2 APIs are slightly different so I post here how to do it.
let client = null; // node socket
let socketId; // chrome API socket id
function toBuffer(ab) {
return new Buffer(new Uint8Array(ab));
}
function toArrayBuffer(buf) {
return new Uint8Array(buf).buffer;
}
function initConnToServer (ip, port) {
return new Promise((resolve, reject) => {
if(typeof chrome !== 'undefined') {
chrome.sockets.tcp.create({}, r => {
socketId = r.socketId;
chrome.sockets.tcp.connect(r.socketId, ip, port, code => resolve(code));
});
} else {
client = new net.Socket(); // return a Node socket
client.connect(port, ip);
client.on('connect', () => resolve());
}
});
};
function sendToServer_simple (data) {
return new Promise((resolve, reject) => {
if(typeof chrome !== 'undefined') {
chrome.sockets.tcp.send(socketId, data, r => {});
chrome.sockets.tcp.onReceive.addListener(receiveInfo => resolve(receiveInfo.data));
} else {
client.write(toBuffer(data));
client.on('data', data => resolve(toArrayBuffer(data)));
}
});
};

Resources