I've created a web socket server with Node.js to connect two Flutter apps. I can post a message to server but when I listen to it on WebApp i receive an array [79,101] instead message (Oi). How can I solve it?
Sink Message
void _sendMessage(data) {
widget.channel.sink.add('Oi');
}
Cliente Stream Builder
StreamBuilder(
stream: channel.stream,
builder: (context, snapshot) {
return Text(snapshot.hasData ? '${snapshot.data}' : 'Null');
},
)
Node.js Server
const WebSocket = require('ws');
// start the server and specify the port number
const port = 8080;
const wss = new WebSocket.Server({ port: port });
console.log(`[WebSocket] Starting WebSocket server on localhost:${port}`);
wss.on('connection', (ws, request) => {
const clientIp = request.sock.remoteAddress;
console.log(`[WebSocket] Client with IP ${clientIp} has connected`);
ws.send('Connected!');
// Broadcast aka send messages to all connected clients
ws.on('message', (message) => {
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message); } })
console.log(`[WebSocket] Message ${message} was received`); });
});
This might not be the solution you are looking for but I would try and convert the response via String.fromCharCodesince the response might be ASCII characters to begin my way of debugging.
Related
When I try to connect to my nodejs server it is showing me this error-
connect_error: [{"cause":{"detailMessage":"Control frames must be final.","stackTrace":[],"suppressedExceptions":[]},"detailMessage":"websocket error","stackTrace":[],"suppressedExceptions":[]}]
I used flutter_socket_io for socket connection
My flutter code
socketIO = SocketIOManager().createSocketIO(
websocketUrl, '/', socketStatusCallback: (status) {
print("web socket -------------status");
print(status);
if (status.toString() == "connect") {
print("connected to server with websocket------------------------");
// socketIO.sendMessage("socket request", jsonEncode({"id": id}));
}
});
socketIO.init();
socketIO.connect().then((value){
print('socket connect');
});
I would like to avoid using the package web_socket_channel which despite its vote doesn't seem to not be actively maintained (many github issues not answered) and doesn't handle errors.
I simply need to connect from Flutter to my WebSocket API in AWS.
How can i do that with dart:io package ? Or is it possible with socket_io_client ? I see that the connection is with http and not wss.
I have found a way in addition to the usual try - catch to handle error in the channel.sink.listen StreamSubscription object with the web_socket_channel package.
You can do the following according to this answer :
_channel = IOWebSocketChannel.connect(
'ws://yourserver.com:port',
);
///
/// Start listening to new notifications / messages
///
_channel.stream.listen(
(dynamic message) {
debugPrint('message $message');
},
onDone: () {
debugPrint('ws channel closed');
},
onError: (error) {
debugPrint('ws error $error');
},
);
This actually works and there is no need to use SocketIO in my use case of course.
I recommend you to use this multiplatform websocket package https://pub.dev/packages/websocket_universal . There you can even use low-level webSocket interactions.
Complete example:
import 'package:websocket_universal/websocket_universal.dart';
/// Example works with Postman Echo server
void main() async {
/// Postman echo ws server (you can use your own server URI)
/// 'wss://ws.postman-echo.com/raw'
/// For local server it could look like 'ws://127.0.0.1:42627/websocket'
const websocketConnectionUri = 'wss://ws.postman-echo.com/raw';
const textMessageToServer = 'Hello server!';
const connectionOptions = SocketConnectionOptions(
pingIntervalMs: 3000, // send Ping message every 3000 ms
timeoutConnectionMs: 4000, // connection fail timeout after 4000 ms
/// see ping/pong messages in [logEventStream] stream
skipPingMessages: false,
/// Set this attribute to `true` if do not need any ping/pong
/// messages and ping measurement. Default is `false`
pingRestrictionForce: false,
);
/// Example with simple text messages exchanges with server
/// (not recommended for applications)
/// [<String, String>] generic types mean that we receive [String] messages
/// after deserialization and send [String] messages to server.
final IMessageProcessor<String, String> textSocketProcessor =
SocketSimpleTextProcessor();
final textSocketHandler = IWebSocketHandler<String, String>.createClient(
websocketConnectionUri, // Postman echo ws server
textSocketProcessor,
connectionOptions: connectionOptions,
);
// Listening to webSocket status changes
textSocketHandler.socketHandlerStateStream.listen((stateEvent) {
// ignore: avoid_print
print('> status changed to ${stateEvent.status}');
});
// Listening to server responses:
textSocketHandler.incomingMessagesStream.listen((inMsg) {
// ignore: avoid_print
print('> webSocket got text message from server: "$inMsg" '
'[ping: ${textSocketHandler.pingDelayMs}]');
});
// Listening to debug events inside webSocket
textSocketHandler.logEventStream.listen((debugEvent) {
// ignore: avoid_print
print('> debug event: ${debugEvent.socketLogEventType}'
' [ping=${debugEvent.pingMs} ms]. Debug message=${debugEvent.message}');
});
// Listening to outgoing messages:
textSocketHandler.outgoingMessagesStream.listen((inMsg) {
// ignore: avoid_print
print('> webSocket sent text message to server: "$inMsg" '
'[ping: ${textSocketHandler.pingDelayMs}]');
});
// Connecting to server:
final isTextSocketConnected = await textSocketHandler.connect();
if (!isTextSocketConnected) {
// ignore: avoid_print
print('Connection to [$websocketConnectionUri] failed for some reason!');
return;
}
textSocketHandler.sendMessage(textMessageToServer);
await Future<void>.delayed(const Duration(seconds: 30));
// Disconnecting from server:
await textSocketHandler.disconnect('manual disconnect');
// Disposing webSocket:
textSocketHandler.close();
}
I have a super simple socket.io node server like below
// Socket!
io.on("connection", (socket) => {
console.log("a user connected");
socket.on("msg", (aaa) => {
console.log(aaa);
});
socket.on("fromServer", (_) => print(_));
console.log(socket.handshake.query)
});
And, here is my Flutter code to connect to the server
// Dart client
IO.Socket socket = IO.io(
'http://192.168.219.102:7199',
IO.OptionBuilder()
.setTransports(['polling'])
.disableAutoConnect()
.setQuery({"hee": 'asdf'})
.build());
socket.connect();
socket.onConnect((_) {
print(_);
});
On the network tab, I see two requests
101 HTTP 490ms
101 WS Pending
When I connect to the socket.io server from the other node.js server, I see the console.log of a user connected on the terminal. However, I see nothing from Flutter.
What can I do to receive the socket message on the server and connect the device.
I want to make a simple client server example with visual studio code. For my mqtt client instance, mosca didn't work. So I created a server with aedes. However, it is not possible to connect to client.js at the moment. I'm sure it's missing on the server side, but I'm not sure how to fix it. I'm very new to this. my codes are below.
Server;
const aedes = require('aedes')()
const server = require('net').createServer(aedes.handle)
const httpServer = require('http').createServer()
const ws = require('websocket-stream')
const port = 1883
const wsPort = 3000
server.listen(port, function () {
console.log('server started and listening on port ', port)
})
ws.createServer({ server: httpServer }, aedes.handle)
httpServer.listen(wsPort, function () {
console.log('websocket server listening on port ', wsPort)
})
Client;
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://192.168.43.40:1883');
client.subscribe('new-user');
client.on('connect', function() {
console.log('connected!');
client.publish('new-user', 'Cansu-' + Math.ceil(Math.random() * 10));
});
client.on('message', function(topic, message) {
console.log(topic, ' : ', message.toString());
client.end();
});
Thank You!!!
I am trying to create a custom LSP.
My goal is to create one language server for both monaco editor (on web) and vscode extension.
Currently I use Node/IPC to connect the vscode-extension with the server.
and ws-jsonrpc to connect monaco editor with the server.
quoting from this article Extending a client with the language server protocol
:
There are multiple ways to use JSON-RPC, but you see these two ways in
most implementations:
Communication is done via the standard input / output, i.e., the command line interface
Communication is performed via TCP/IP, i.e., network messages similar to HTTP
I should be able to use JSON-RPC for both communication (internal communication between processes which is the vscode-extesion in my case , and external communication which is monaco-editor in my case)
Here is how I am launching the server for the moment:
For IPC communication:
const languageServer = new LanguageServer(createConnection(ProposedFeatures.all));
languageServer.start();
For WebSocket RPC:
import * as express from "express";
import * as ws from "ws";
import * as rpc from "vscode-ws-jsonrpc";
import * as url from "url";
import * as http from "http";
import * as net from "net";
const app = express();
const server = app.listen(3000);
const wss = new ws.Server({
noServer: true,
perMessageDeflate: false
});
function launch(socket : rpc.IWebSocket ){
const reader = new rpc.WebSocketMessageReader(socket);
const writer = new rpc.WebSocketMessageWriter(socket);
const languageServer = new LanguageServer(createConnection(reader, writer));
languageServer.start();
}
server.on('upgrade', (request: http.IncomingMessage, socket: net.Socket, head: Buffer) => {
const pathname = request.url ? url.parse(request.url).pathname : undefined;
console.log("server on upgrade ", pathname);
if (pathname === '/sampleServer') {
wss.handleUpgrade(request, socket, head, (webSocket: any) => {
const socket: rpc.IWebSocket = {
send: (content: any) => webSocket.send(content, (error: any) => {
if (error) {
throw error;
}
}),
onMessage: (cb: any) => webSocket.on('message', cb),
onError: (cb: any) => webSocket.on('error', cb),
onClose: (cb: any) => webSocket.on('close', cb),
dispose: () => webSocket.close()
};
// launch the server when the web socket is opened
if (webSocket.readyState === webSocket.OPEN) {
launch(socket);
} else {
webSocket.on('open', () => {
launch(socket);
});
}
});
}
})
The server that you are using should not operate with multiple clients using it at the same time. It even says: "the protocol currently assumes that one server serves one tool.". Also, maybe read this article about your topic. **https://code.visualstudio.com/api/language-extensions/language-server-extension-guide **