WebSocket Closes with Protocol Error 1002 - javascript

I m implementing WebSocket messages command-line client.
I have checked that this error corresponds to the problem with the protocol. I upgraded ws to the newest 7.4.1. At backend I use Spring Boot Websockets at version 2.3.4.RELEASE.
The 2 main causes of this are said to be packet loss or malformed messages.
I have made some checks to check those but none seem valid.
The messages I test are small so it shouldn't be the case with message size. The connection is fully on localhost.
I test the solution with 3 users and sometimes I get this error sometimes not.
Can someone help me figure out how to get rid of this type of error?
Here is the code I use for client to send messages:
async function test(number_of_messages, break_between_messages) {
const websocket = new WebSocket(url...)
websocket.on('message', function incoming(data) {
console.log(getMessage("Received", data))
});
websocket.on('close', function(data) {
console.log('Disconnected!!!! ' + data.toString());
});
const opened = await connection(websocket)
//Wait 5 seconds
await sleep(5_000);
if (opened) {
for (i = 0; i < number_of_messages; i++) {
for (const chatId of chatIds) {
let content = i.toString() + " from " + user;
let msg = JSON.stringify({
"chatId": chatId,
"author": user,
"content": content
})
websocket.send(msg)
let message = getMessage("Sent", msg)
console.log(message)
}
await sleep(break_between_messages);
}
} else {
console.log("ERROR on Opening Connection")
return
}
// Wait 1 minute
await sleep(60_000);
websocket.close()
}
With backend code:
#Component
#ServerEndpoint(value = "/webSocket/{username}",
encoders = MessageRepresentationEncoder.class, decoders = MessageRepresentationDecoder.class)
public class MessagingSocket {
private Logger logger = LoggerFactory.getInstance();
private Session session;
private MessagingAPI messagingAPI = MessagingAPIFactory.createAPI();
private UserSocketRegistry userSocketRegistry = UserSocketRegistry.createRegistry();
private SessionUserRegistry sessionUserRegistry = SessionUserRegistry.createRegistry();
#OnOpen
public void onOpen(Session session, #PathParam("username") String username) {
this.session = session;
logger.log(LoggingType.INFO, "Started new session " + session.getId());
logger.log(LoggingType.INFO, username + " connected");
userSocketRegistry.addSessionForUser(this, username);
sessionUserRegistry.addSessionForUser(session, username);
}
#OnMessage //Allows the client to send message to the socket.
public void onMessage(MessageRepresentation messageRepresentation) {
logger.log(LoggingType.INFO, "Received " + messageRepresentation.toString());
messagingAPI.write(WriteMessage.from(UUID.fromString(messageRepresentation.chatId), messageRepresentation.author, messageRepresentation.content));
broadcastToChat(messageRepresentation);
}
private void broadcastToChat(MessageRepresentation message) {
final List<MessagingSocket> sockets = messagingAPI.getUsersConnectedToChat(UUID.fromString(message.chatId)).stream().filter(user -> userSocketRegistry.hasSocketFor(user.getName()))
.map(user -> userSocketRegistry.getSocketFor(user.getName())).collect(Collectors.toList());
logger.log(LoggingType.INFO, "Starting broadcast of " + message.content + " from " + message.author + " for " + String.join(",", messagingAPI.getUsersConnectedToChat(UUID.fromString(message.chatId)).stream().map(x -> x.getName()).collect(Collectors.toList())));
for (MessagingSocket messagingSocket : sockets) {
logger.log(LoggingType.INFO, "Broadcasting message" + message.content + " to " + messagingSocket.session.getId());
messagingSocket.sendMessage(message);
}
}
private void sendMessage(MessageRepresentation message) {
try {
this.session.getBasicRemote().sendObject(message);
} catch (IOException | EncodeException e) {
logger.log(LoggingType.ERROR, "Caught exception while sending message to Session Id: " + this.session.getId());
}
}
#OnClose
public void onClose(Session session) {
String user = sessionUserRegistry.getUserFor(session);
logger.log(LoggingType.INFO, "User " + user + " with session " + this.session.getId() + " disconnected ");
sessionUserRegistry.removeSession(session);
userSocketRegistry.removeUser(user);
}
}
And MessageRepresentation as:
public class MessageRepresentation {
public String chatId;
public String author;
public String content;
#Override
public String toString() {
return "MessageRepresentation{" +
"chatId='" + chatId + '\'' +
", author='" + author + '\'' +
", content='" + content + '\'' +
'}';
}
}
After further investigation I m getting the following exception:
java.lang.IllegalStateException: The remote endpoint was in state [TEXT_FULL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1243)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:1205)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:191)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendObject(WsRemoteEndpointImplBase.java:600)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendObject(WsRemoteEndpointBasic.java:74)
at presentation.frontend.websockets.server.MessagingSocket.sendMessage(MessagingSocket.java:64)
at presentation.frontend.websockets.server.MessagingSocket.broadcastToChat(MessagingSocket.java:57)
at presentation.frontend.websockets.server.MessagingSocket.onMessage(MessagingSocket.java:47)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:80)
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:402)
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:119)
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:502)
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:301)
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:82)
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171)
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148)
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
java.lang.IllegalStateException: Message will not be sent because the WebSocket session has been closed

I could be off the mark here but I think this is probably due to the message containing invalid UTF8 or some such. i.e. malformed.
If this sounds like it could be the cause the simple fix would be to encode the msg
let msg = JSON.stringify({
"chatId": chatId,
"author": user,
"content": content
})
to
let msg = unescape(encodeURIComponent(JSON.stringify({
"chatId": chatId,
"author": user,
"content": content
})));
Then decode on the other side...
JSON.parse(decodeURIComponent(escape( ... )))

The solution to this one involved 2 steps.
1: Find the error stacktrace
#OnError
public void onError(Session session, Throwable throwable) {
logger.log(LoggingType.ERROR, "Error for " + session.getId() + " caused by: " + throwable.getMessage());
throwable.printStackTrace();
}
2: Change synchronous BasicRemote to asynchronous AsyncRemote in broadcasting messages (this is important when the number of messages increased)
private void sendMessage(MessageRepresentation message) {
this.session.getAsyncRemote().sendObject(message);
}

Related

Is there a way to send an image and text field items from react js(hooks) to spring boot api endpoint with the same url at the same time

this is the spring boot API endpoint which receives request from react js frontend
#PostMapping(value = "/upload", consumes = {MediaType.APPLICATION_JSON_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<MessageResponse> uploadFile(#RequestPart("fileDB") String fileDB,
#RequestPart("file") MultipartFile file) {
String message = "";
try {
storageService.store(file, fileDB);
message = "Uploaded the file successfully: " + file.getOriginalFilename();
return ResponseEntity.status(HttpStatus.OK).body(new MessageResponse(message));
} catch (Exception e) {
message = "Could not upload the file: " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new
MessageResponse(message));
}
}

How to send data from Node to another server

I am trying to figure out a way to use Node as a client that would send out data to a server listening on an Android app. The android app will initially send a post request to the Node server with its public IP address and the port it will be listening on (socket). Once there is anything new, the Node server would then send a packet of JSON data onto that particular app via the registered socket.
Is this possible in Node, and if not how can I implement it in Javascript, or what is the best way to implement this?
Here is the Android app server
public class AndroidAppLocalServer {
Activity activity;
ServerSocket serverSocket;
String message = "";
static final int socketServerPORT = 8080;
public AndroidAppLocalServer(Activity activity) {
this.activity = activity;
Thread socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
}
public int getPort() {
return socketServerPORT;
}
public void onDestroy() {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerThread extends Thread {
int count = 0;
#Override
public void run() {
try {
// create ServerSocket using specified port
serverSocket = new ServerSocket(socketServerPORT);
while (true) {
// block the call until connection is created and return
// Socket object
Socket socket = serverSocket.accept();
count++;
message += "#" + count + " from "
+ socket.getInetAddress() + ":"
+ socket.getPort() + "\n";
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.v("MyApp", message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(socket, count);
socketServerReplyThread.run();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread {
private Socket hostThreadSocket;
int cnt;
SocketServerReplyThread(Socket socket, int c) {
hostThreadSocket = socket;
cnt = c;
}
#Override
public void run() {
OutputStream outputStream;
String msgReply = "Hello from AndroidAppLocalServer, you are #" + cnt;
try {
outputStream = hostThreadSocket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(msgReply);
printStream.close();
message += "replayed: " + msgReply + "\n";
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.v("MyApp", message);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message += "Something wrong! " + e.toString() + "\n";
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.v("MyApp", message);
}
});
}
}
public String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "AndroidAppLocalServer running at : " + inetAddress.getHostAddress();
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
}
Yes you can do this in Node.js, assuming that the App runs on a phone that is actually publicly reachable. Since you are using a plain TCP socket in your Android application, you can verify first by manually connecting the socket by using a tool such as netcat or telnet (e.g., netcat <PUBLIC-IP> 8080).
If this works you can do the same thing from within Node.js by using the net.Socket class.
const net = require('net');
const client = new net.Socket();
client.connect(8080, '<PUBLIC-IP>', () => {
// callback, when connection successfull
client.write('Data sent to the App');
});
client.on('data', (data) => {
// callback, when app replies with data
});
client.on('close', (data) => {
// callback, when socket is closed
});
However, depending on what you actually try to achieve, you might want check out how Android applications usually implement push notifications.

Connection refused when Using WebSocet to connect to server

i am try to connect to glassFish-server4.1.1 from my android application
but give me Error failed to connect to /localhost (port 8080) after 90000ms
i change port on server but give me same error
......
it connect to server only on netbeans but on android give me faild and below my code
server code `
#ServerEndpoint("/echo")
public class WebSocketClass {
/**
* #param session
* #OnOpen allows us to intercept the creation of a new session.
* The session class allows us to send data to the user.
* In the method onOpen, we'll let the user know that the handshake was
* successful.
*/
#OnOpen
public void onOpen(Session session){
System.out.println(session.getId() + " has opened a connection");
try {
session.getBasicRemote().sendText("Connection Established");
} catch (IOException ex) {
}
}
/**
* When a user sends a message to the server, this method will intercept the message
* and allow us to react to it. For now the message is read as a String.
* #param message
* #param session
*/
#OnMessage
public void onMessage12(String message, Session session){
System.out.println("Message from " + session.getId() + ": " + message);
try {
session.getBasicRemote().sendText(message);
} catch (IOException ex) {
}
}
/**
* The user closes the connection.
*
* Note: you can't send messages to the client from this method
* #param session
*/
#OnClose
public void onClose(Session session){
System.out.println("Session " +session.getId()+" has ended");
}}
client code
private void connectWebSocket() {
URI uri;
try {
uri = new URI("ws://localhost:8080/WebApplication1/echo");
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
mWebSocketClient = new WebSocketClient(uri) {
#Override
public void onOpen(ServerHandshake serverHandshake) {
Log.i("Websocket", "Opened");
mWebSocketClient.send("Hello from " + Build.MANUFACTURER + " " + Build.MODEL);
}
#Override
public void onMessage(String s) {
final String message = s;
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView textView = (TextView)findViewById(R.id.messages);
textView.setText(textView.getText() + "\n" + message);
}
});
}
#Override
public void onClose(int i, String s, boolean b) {
Log.i("Websocket", "Closed " + s);
}
#Override
public void onError(Exception e) {
Log.i("Websocket", "Error " + e.getMessage());
}
};
mWebSocketClient.connect();
}
i do't know why this error?
can any one help me...
Maybe you should change the IP to reflect the IP where glassfish server is installed on the client

Uncaught type error: Cannot read property of 'send' undefined

I am trying to send a message to my websocket in the form of json but I got this error in the developer console when I run the web app. I know this error occurs when the element could not be found. However, isn't 'send' a default member of websocket? Why wouldn't it be found? The error occurs at my last line of code.The code for my .js file is as follows:
// to keep the session id
var sessionId = '';
// name of the client
var name = '';
$(document).ready(function() {
$("#form_submit, #form_send_message").submit(function(e) {
e.preventDefault();
join();
});
});
var webSocket;
/**
* Connecting to socket
*/
function join() {
// Checking person name
if ($('#input_name').val().trim().length <= 0) {
alert('Enter your name');
} else {
name = $('#input_name').val().trim();
$('#prompt_name_container').fadeOut(1000, function() {
// opening socket connection
openSocket();
});
}
return false;
}
/**
* Will open the socket connection
*/
function openSocket() {
// Ensures only one connection is open at a time
if (webSocket !== undefined && webSocket.readyState !== WebSocket.CLOSED) {
return;
}
var wsUrl;
if (window.location.protocol == 'http:') {
wsUrl = 'ws://' + window.location.host + ':8000/chat'+'?name='+name;
} else {
wsUrl = 'wss://' + window.location.host + ':8443/chat'+'?name='+name;
}
console.log('WebSockets Url : ' + wsUrl);
var webSocket = new WebSocket(wsUrl);
// Create a new instance of the websocket
//webSocket = new WebSocket("ws://jbosslew-weihao.rhcloud.com:8000/" );
/**
* Binds functions to the listeners for the websocket.
*/
webSocket.onopen = function(event) {
$('#message_container').fadeIn();
if (event.data === undefined)
return;
};
webSocket.onmessage = function(event) {
// parsing the json data
parseMessage(event.data);
};
webSocket.onclose = function(event) {
};
}
/**
* Sending the chat message to server
*/
function send() {
var message = $('#input_message').val();
if (message.trim().length > 0) {
sendMessageToServer('message', message);
} else {
alert('Please enter message to send!');
}
}
/**
* Closing the socket connection
*/
function closeSocket() {
webSocket.close();
$('#message_container').fadeOut(600, function() {
$('#prompt_name_container').fadeIn();
// clearing the name and session id
sessionId = '';
name = '';
// clear the ul li messages
$('#messages').html('');
$('p.online_count').hide();
});
}
/**
* Parsing the json message. The type of message is identified by 'flag' node
* value flag can be self, new, message, exit
*/
function parseMessage(message) {
var jObj = $.parseJSON(message);
// if the flag is 'self' message contains the session id
if (jObj.flag == 'self') {
sessionId = jObj.sessionId;
} else if (jObj.flag == 'new') {
// if the flag is 'new', a client joined the chat room
var new_name = 'You';
// number of people online
var online_count = jObj.onlineCount;
$('p.online_count').html(
'Hello, <span class="green">' + name + '</span>. <b>'
+ online_count + '</b> people online right now')
.fadeIn();
if (jObj.sessionId != sessionId) {
new_name = jObj.name;
}
var li = '<li class="new"><span class="name">' + new_name + '</span> '
+ jObj.message + '</li>';
$('#messages').append(li);
$('#input_message').val('');
} else if (jObj.flag == 'message') {
// if the json flag is 'message', it means somebody sent the chat
// message
var from_name = 'You';
if (jObj.sessionId != sessionId) {
from_name = jObj.name;
}
var li = '<li><span class="name">' + from_name + '</span> '
+ jObj.message + '</li>';
// appending the chat message to list
appendChatMessage(li);
$('#input_message').val('');
} else if (jObj.flag == 'exit') {
// if the json flag is 'exit', it means somebody left the chat room
var li = '<li class="exit"><span class="name red">' + jObj.name
+ '</span> ' + jObj.message + '</li>';
var online_count = jObj.onlineCount;
$('p.online_count').html(
'Hello, <span class="green">' + name + '</span>. <b>'
+ online_count + '</b> people online right now');
appendChatMessage(li);
}
}
/**
* Appending the chat message to list
*/
function appendChatMessage(li) {
$('#messages').append(li);
// scrolling the list to bottom so that new message will be visible
$('#messages').scrollTop($('#messages').height());
}
/**
* Sending message to socket server message will be in json format
*/
function sendMessageToServer(flag, message) {
var json = '{""}';
// preparing json object
var myObject = new Object();
myObject.sessionId = sessionId;
myObject.message = message;
myObject.flag = flag;
// converting json object to json string
json = JSON.stringify(myObject);
// sending message to server
webSocket.send(json); // Uncaught type error occurs here
}
If it is also relevant, my java code for my server socket is as follows:
package info.androidhive.webmobilegroupchat;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.common.collect.Maps;
#ServerEndpoint("/chat")
public class SocketServer {
// set to store all the live sessions
private static final Set<Session> sessions = Collections
.synchronizedSet(new HashSet<Session>());
// Mapping between session and person name
private static final HashMap<String, String> nameSessionPair = new HashMap<String, String>();
private JSONUtils jsonUtils = new JSONUtils();
// Getting query params
public static Map<String, String> getQueryMap(String query) {
Map<String, String> map = Maps.newHashMap();
if (query != null) {
String[] params = query.split("&");
for (String param : params) {
String[] nameval = param.split("=");
map.put(nameval[0], nameval[1]);
}
}
return map;
}
/**
* Called when a socket connection opened
* */
#OnOpen
public void onOpen(Session session) {
System.out.println(session.getId() + " has opened a connection");
Map<String, String> queryParams = getQueryMap(session.getQueryString());
String name = "";
if (queryParams.containsKey("name")) {
// Getting client name via query param
name = queryParams.get("name");
try {
name = URLDecoder.decode(name, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// Mapping client name and session id
nameSessionPair.put(session.getId(), name);
}
// Adding session to session list
sessions.add(session);
try {
// Sending session id to the client that just connected
session.getBasicRemote().sendText(
jsonUtils.getClientDetailsJson(session.getId(),
"Your session details"));
} catch (IOException e) {
e.printStackTrace();
}
// Notifying all the clients about new person joined
sendMessageToAll(session.getId(), name, " joined conversation!", true,
false);
}
/**
* method called when new message received from any client
*
* #param message
* JSON message from client
* */
#OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message from " + session.getId() + ": " + message);
String msg = null;
// Parsing the json and getting message
try {
JSONObject jObj = new JSONObject(message);
msg = jObj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
// Sending the message to all clients
sendMessageToAll(session.getId(), nameSessionPair.get(session.getId()),
msg, false, false);
}
/**
* Method called when a connection is closed
* */
#OnClose
public void onClose(Session session) {
System.out.println("Session " + session.getId() + " has ended");
// Getting the client name that exited
String name = nameSessionPair.get(session.getId());
// removing the session from sessions list
sessions.remove(session);
// Notifying all the clients about person exit
sendMessageToAll(session.getId(), name, " left conversation!", false,
true);
}
/**
* Method to send message to all clients
*
* #param sessionId
* #param message
* message to be sent to clients
* #param isNewClient
* flag to identify that message is about new person
* #param isExit
* flag to identify that a person left the conversation
* */
private void sendMessageToAll(String sessionId, String name,
String message, boolean isNewClient, boolean isExit) {
// Looping through all the sessions and sending the message individually
for (Session s : sessions) {
String json = null;
// Checking if the message is about new client joined
if (isNewClient) {
json = jsonUtils.getNewClientJson(sessionId, name, message,
sessions.size());
} else if (isExit) {
// Checking if the person left the conversation
json = jsonUtils.getClientExitJson(sessionId, name, message,
sessions.size());
} else {
// Normal chat conversation message
json = jsonUtils
.getSendAllMessageJson(sessionId, name, message);
}
try {
System.out.println("Sending Message To: " + sessionId + ", "
+ json);
s.getBasicRemote().sendText(json);
} catch (IOException e) {
System.out.println("error in sending. " + s.getId() + ", "
+ e.getMessage());
e.printStackTrace();
}
}
}
}
According to Tiny Giant, I've accidentally redeclared my variable webSocket, instead of using the global version of it, causing my webSocket to be undefined at that moment.

Send Message to Socket, from C# client to node.js + socket.io server

I would like to send a message through socket with c# windows store app client to node.js and socket.io server
my client side code is like this (c#)
private async void SendDatatoSocket(string sendTextData)
{
if (!connected)
{
StatusText = "Must be connected to send!";
return;
}
Int32 wordlength = 0; // Gets the UTF-8 string length.
try
{
OutputView = "";
StatusText = "Trying to send data ...";
txtblock_showstatus.Text += System.Environment.NewLine;
txtblock_showstatus.Text += StatusText;
Debug.WriteLine(StatusText);
// add a newline to the text to send
string sendData = sendTextData + Environment.NewLine;
DataWriter writer = new DataWriter(clientSocket.OutputStream);
wordlength = sendData.Length; // Gets the UTF-8 string length.
// Call StoreAsync method to store the data to a backing stream
await writer.StoreAsync();
StatusText = "Data was sent" + Environment.NewLine;
txtblock_showstatus.Text += System.Environment.NewLine;
txtblock_showstatus.Text += StatusText;
Debug.WriteLine(StatusText);
// detach the stream and close it
writer.DetachStream();
writer.Dispose();
}
catch (Exception exception)
{
// If this is an unknown status,
// it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusText = "Send data or receive failed with error: " + exception.Message;
txtblock_showstatus.Text += System.Environment.NewLine;
txtblock_showstatus.Text += StatusText;
Debug.WriteLine(StatusText);
// Could retry the connection, but for this simple example
// just close the socket.
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
// Now try to receive data from server
try
{
OutputView = "";
StatusText = "Trying to receive data ...";
Debug.WriteLine(StatusText);
txtblock_showstatus.Text += System.Environment.NewLine;
txtblock_showstatus.Text += StatusText;
DataReader reader = new DataReader(clientSocket.InputStream);
string receivedData;
reader.InputStreamOptions = InputStreamOptions.Partial;
var count = await reader.LoadAsync(512);
if (count > 0)
{
receivedData = reader.ReadString(count);
Debug.WriteLine(receivedData);
txtblock_showstatus.Text += System.Environment.NewLine;
txtblock_showstatus.Text += receivedData;
}
}
catch (Exception exception)
{
// If this is an unknown status,
// it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusText = "Receive failed with error: " + exception.Message;
Debug.WriteLine(StatusText);
// Could retry, but for this simple example
// just close the socket.
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
}
and my code in server side is like this (node.js)
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 1337;
// Create a server instance, and chain the listen function to it
// The function passed to net.createServer() becomes the event handler for the 'connection' event
// The sock object the callback function receives UNIQUE for each connection
net.createServer(function (sock) {
// We have a connection - a socket object is assigned to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.on('data', function (data) {
console.log(sock.name + "> " + data, sock);
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function (data) {
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
sock.end();
});
}).listen(PORT, HOST);
before, I changed the node.js code to
net.createServer(function (sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.write("Hello");
//});
The message "Hello" appear on my client side correctly
the problem is that when I add these lines, the code doesn't work anymore.
sock.on('data', function (data) {
console.log(sock.name + "> " + data, sock);
});
The message I sent is just a word of string.
It seems like the message doesn't go right in this.
sock.on('data', function (data) {} );
Is there anyway that I can make this thing work?
Thank you.
this is application Server side (Node Js):
var net = require('net');
var server = net.createServer(function(socket) { //Create the server and pass it the function which will write our data
console.log('CONNECTED: ' + socket.remoteAddress + ':' + socket.remotePort);
socket.write("Hello\n");
socket.write("World!\n");
//when to open the C # application write in the Desktop console "hello world"
socket.on('data', function (data) {
console.log(socket.name + "> " + data);
socket.write("Message from server to Desktop");
socket.end("End of communications.");
});
});
server.listen(3000); //This is the port number we're listening to
Into my C# Application I have write:
static void Main(string[] args)
{
TcpClient client = new TcpClient();
client.Connect("192.168.x.x", 3000); //Connect to the server on our local host IP address, listening to port 3000
NetworkStream clientStream = client.GetStream();
System.Threading.Thread.Sleep(1000); //Sleep before we get the data for 1 second
while (clientStream.DataAvailable)
{
byte[] inMessage = new byte[4096];
int bytesRead = 0;
try
{
bytesRead = clientStream.Read(inMessage, 0, 4096);
}
catch { /*Catch exceptions and handle them here*/ }
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine(encoder.GetString(inMessage, 0, bytesRead));
}
//******************** SEND DATA **********************************
string message = "Send message from Desktop to Server NodeJs!";
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Call StoreAsync method to store the data to a backing stream
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
//*****************************************************************
client.Close();
System.Threading.Thread.Sleep(10000); //Sleep for 10 seconds
}
this is my my working solution

Categories

Resources