client.on not getting data on single connect - javascript

I am using net module to connect client with my server. And here is my code.
const Net = require('net');
client = Net.connect(parseInt(port), host, function() {
console.log('server connected')
})
console.log("ooooooooooooooooooooooooooooo")
client.on('data', function(chunk) {
let data = chunk.toString()
console.log(data)
});
client.on('error', function(error) {
console.error('error', error);
});
The issue is when I connect it with single client it doesn't give me data inside client.on('data' but when I connect it will two or more clients it gets connected and I am getting my data. Someone pls help.
If there any other module I can use ?

I have three Java TCP servers each running on their own thread, this particular one handles localhost connections from the NodeJS server which is mainly TEXT or JSON objects. It will read a command and respond.
The NodeJS server then sends that data back to the client browser using socket.io.
/*
* Handle the nodejs interaction on localhost port 2000
*/
public class DeviceServer3 extends Thread {
private static DeviceServer dev_server = null;
private boolean quit = false;
private final int port = 2000;
public DeviceServer3(DeviceServer server) {
dev_server = server; // store original server
}
public void quitSignal() { // safely shutdown thread
System.out.println("WLMedia Node Java Server exiting...");
quit = true;
while (dev_server.thread_count.get() != 0) {
try { Thread.sleep(5);
} catch (InterruptedException ex) {}
}
}
#Override
public void run() { // main thread
ServerSocket listen_socket = null;
while (!quit) {
try {
listen_socket = new ServerSocket(port);
//listen_socket.setSoTimeout(5000);
listen_socket.setReuseAddress(true);
while (!quit) {
Socket connection = listen_socket.accept();
checkSocket(connection);
}
} catch (IOException e) {
System.out.println("Node Server catch: " + e.getLocalizedMessage());
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
} finally {
try {
if (listen_socket != null) {
listen_socket.close();
}
} catch (IOException e) {
System.out.println("server finally: " + e.getMessage());
}
}
}
}
private void checkSocket(Socket socket) {
// Only allow 'localhost' connections
if (socket.getInetAddress().isLoopbackAddress()) {
handleSocket(socket); // TODO change to a thread
} else {
System.out.println("WARNING: Outside connection attempt from: "
+ socket.getInetAddress().toString());
}
try {
socket.close();
System.out.println("Port 2000 socket disconnected");
} catch (IOException e) {
e.printStackTrace();
}
}
private BufferedReader getBufferedReader(Socket socket)
throws IOException {
InputStreamReader is = new InputStreamReader(socket.getInputStream());
return new BufferedReader(is);
}
private BufferedWriter getBufferedWriter(Socket socket)
throws IOException {
OutputStreamWriter os = new OutputStreamWriter(socket.getOutputStream());
return new BufferedWriter(os);
}
// Safely here to handle the socket connection
private void handleSocket(Socket socket) {
System.out.println("Port 2000 socket connected");
try {
BufferedReader br = getBufferedReader(socket);
BufferedWriter bw = getBufferedWriter(socket);
String command = br.readLine();
switch (command) {
/* Media Manager */
case "media_areas":
System.out.println("NodeJS media_areas");
get_media_areas(br, bw);
break;
case "media_categories":
System.out.println("NodeJS media_categories");
get_media_categories(br, bw);
break;
/* Device manager */
case "devices_get":
System.out.println("NodeJS get_devices");
get_devices(br, bw);
break;
default:
System.out.println("NodeJS command not recognised: " + command);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* Handle commands
*/
// Command: media_areas
private void get_media_areas(BufferedReader br, BufferedWriter bw)
throws IOException {
JSONArray area_list = new JSONArray(); // create JSON array
System.out.println("Getting Area list");
synchronized (dev_server.library.media_lock) {
for (Area area : dev_server.library.media) {
area_list.put(area.name);
System.out.println("Area: " + area.name);
}
}
bw.write(area_list.toString()); // send JSON array back to NodeJS server
bw.flush(); // ensure a flush before the socket is closed
}
// ...
The issue I had was the data not being sent to the Node server, which using the flush() fixed that issue before the socket was closed.
This is a snipped from the Node server which connects to the Java TCP server and then sends the JSON data back to the clients browser.
const global = require("../global/global.js");
const login = require("../login/login");
const node_port = 2000;
const host = "localhost";
function m_get_media_areas(socket) {
// check user logged in (return to login page)
if (!login.check_logged_in(socket)) { return; }
client = new global.net.Socket(); // connect to Java TCP server
client.connect({port: node_port, host: host}, () =>
{ client.write("media_areas\n"); });
// send the JSON string to clients browser over socket.io
client.on("data", (data) => { socket.emit("media_areas", data); });
client.on("end", () => {});
client.on("error", () => { console.log("ERROR: getting areas"); });
}
module.exports = {
get_media_areas : m_get_media_areas,
// ...
}
On the clients browser side I just use socket.io to emit the command and then just listent for the event so that I can use the data.
// get area list
socket.emit("media_areas");
// media variables
media_area = "";
media_category = "";
media_videos = {}; // a JSON array of JSON objects
socket.on("media_areas", (res) => {
json = JSON.parse(new TextDecoder().decode(res));
$("#list_media_area").empty();
$("#list_media_category").empty();
$("#list_media_videos").empty();
json.forEach(area => {
if (area !== null && area !== "")
$("#list_media_area").append("<li>" + area);
});
media_area = "";
$("#list_media_area li").click(function() {
$(this).addClass("li_selected").siblings().removeClass("li_selected");
media_area = $(this).text();
console.log("Media Area Selected: " + media_area);
$("#accordion_video_category").click();
socket.emit("media_categories", {"area": media_area});
});
});
That's how I've managed to get around it and it works for me great.
The Java JSON library I used is:
https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22

Without more information on your server implementation it is difficult to answer this question directly. Here is a general example that should be helpful for you.
server.js
const net = require('net');
net.createServer(function(socket) {
// listen for data from the client
socket.on('data', function(data) {
console.log('data from client: ', String(data));
});
// write data to the client
socket.write('hello from the server\n');
}).listen('3000', function() {
console.log('server listening on 3000');
});
client.js
const net = require('net');
const socket = net.connect(3000, 'localhost')
// listen for data from the server
socket.on('data', function(data) {
console.log('data from server: ', String(data));
});
// write data to the server
socket.write('hello from the client\n');
First run node server.js then from a separate tab run node client.js. You should see the communication between the server and client. Another tool that may be helpful for you is telnet, which provides a simple tcp interface. You can test your server by using telnet localhost 3000

Related

Can't connect client (Javascript) to existing socket server

I have an existing socket server that listens on port 6868. It is written in Java.
I need to connect a client to the server. The client is coded in Javascript in my React app.
I have tried just about every possible combination of tutorials I have found on the internet but I still can't get the client to connect.
import * as io from "socket.io-client";
export default () => {
// eslint-disable-next-line no-restricted-globals
self.onmessage = (message) => {
const data = message.data;
try {
var socket = io("http://localhost:6868/");
} catch (error) {
console.log("do nothing: " + error);
}
};
};
No matter what, I get the same error: ReferenceError: socket_io_client__WEBPACK_IMPORTED_MODULE_0___default is not defined.
This is the version I am using as seen in package.json: "socket.io-client": "^4.4.0"
I installed it with this command: npm i socket.io-client
Turns out that socket.io can't be used to connect to the ServerSocket that I have in Java. To fix this, I changed ServerSocket to be a WebSocketServer.
Here is all of the code needed to make Java WebSocket connect with JavaScript client:
WebsocketServer.java
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;
public class WebsocketServer extends WebSocketServer {
private static int TCP_PORT = 6868;
private static Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(TCP_PORT));
conns = new HashSet<>();
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
conn.send("hello!!");
System.out.println("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
conns.remove(conn);
System.out.println("Closed connection to " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onMessage(WebSocket conn, String message) {
System.out.println("Message from client: " + message);
for (WebSocket sock : conns) {
sock.send("SENDING BACK" + message);
}
}
#Override
public void onError(WebSocket conn, Exception ex) {
//ex.printStackTrace();
if (conn != null) {
conns.remove(conn);
// do some thing if required
}
System.out.println("ERROR from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
public static Set<WebSocket> getConns() {
return conns;
}
}
And launch the server from main() with new WebsocketServer().start();
client.js
var connection = new WebSocket("ws://127.0.0.1:6868");
connection.onopen = function () {
console.log("Connected!");
connection.send("Ping"); // Send the message 'Ping' to the server
};
// Log errors
connection.onerror = function (error) {
console.log("WebSocket Error " + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log("Server: " + e.data);
};
And the dependency for the Java Web Socket:
<dependency>
<groupId>
org.java-websocket
</groupId>
<artifactId>
Java-WebSocket
</artifactId>
<version>
1.3.0
</version>
</dependency>

SignalR client side method not firing on from server side button click

I am having a Visual Studio 2019 based SignalR Application, where client connects to server.
Following javascript function is called when a page is loaded and it connects to a running server with a successful connectionid.
function Connect() {
$.connection.hub.url = url;
stockTickerHubProxy = $.connection.mobileStockTickerHub;
if (stockTickerHubProxy) {
$.connection.hub.start().done(function () {
console.log("Connected...");
connectionId = $.connection.hub.id;
console.log(connectionId)
stockTickerHubProxy.server.setUserName(code);
})
.fail(function () {
alert("Can't connect");
})
;
stockTickerHubProxy.client.addMessage = function (name, message) {
console.log(name + ":" + message);
}
stockTickerHubProxy.client.showtradenotification = function (msg) {
alert(msg)
}
$.connection.hub.disconnected(function () {
console.log("Server disconnected.");
});
$.connection.hub.reconnecting(function () {
console.log("Server reconnecting...");
});
$.connection.hub.reconnected(function () {
console.log("Server reconnected...");
Connect();
});
$.connection.hub.error(function (error) {
console.log('SignalR error: ' + error)
});
}
}
On server, I am executing following test code for checking the function running in javascript html page. Following is the code.
private async void button1_ClickAsync(object sender, EventArgs e)
{
mhubContext = GlobalHost.ConnectionManager.GetHubContext<MobileStockTickerHub>();
await mhubContext.Clients.All.showtradenotification("Hello");
}
Following is the hub class MobileStockTickerHub
public class MobileStockTickerHub : Hub
{
//Called when a client is connected
public override Task OnConnected()
{
_users.TryAdd(Context.ConnectionId, Context.ConnectionId);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
string username;
_users.TryRemove(Context.ConnectionId, out username);
return base.OnDisconnected(stopCalled);
}
public override Task OnReconnected()
{
_users.TryAdd(Context.ConnectionId, Context.ConnectionId);
return base.OnReconnected();
}
public string SetUserName(string userName)
{
_users[Context.ConnectionId] = userName;
return "Received ping from " + userName;
}
}
Again, when button1_ClickAsync is fired, there is no activity on the webpage, that should fire showtradenotification with an alert message.
Let me know where I am wrong.
Thanks.
Move your client function before your hub.start. You should always register at least one function before your start. See the note regarding in the docs.

What is a way to return exception caught in asp.net Web Api to Angular 8?

I have my angular service like:
GetPaymentDeadlineExtension(data: PatientInput): Observable<any> {
return this.httpClient.post<any>(
this.root + `/api/PaymentDeadline/RegisterPatientInput`,data);
}
in my web api controller:
[Route("RegisterPatientInput")]
public SrvInvoiceCompositView[] RegisterGetPaymentDeadlineExtension(PatientInput data)
{
SrvInvoiceCompositView[] list = null;
string ContractNo = String.Empty;
string DktInvoiceNo = String.Empty;
try
{
ContractNo = data.BillNumber.Split('-')[0];
DktInvoiceNo = data.BillNumber.Split('-')[1];
list = DkService.SrvFindInvoiceCompositViewDentaPay(DktInvoiceNo, data.Amount, data.PatientNumber, ContractNo);
}
catch(Exception ex)
{
// exception to be returned to angular app.
}
return list;
}
and in my component.ts file:
this.homePageService.GetPaymentDeadlineExtension(this.input).subscribe(
data=>
{
this.patientInfo = data;
},
error=>
{
//i want to get my ex.message here, so i can display it
}
)
this.homePageService.GetPaymentDeadlineExtension(this.input)
.pipe(catchError((error)=> { handleError here}).subscribe(
data=>
{
this.patientInfo = data;
}
)
More info: https://www.learnrxjs.io/learn-rxjs/operators/error_handling/catch
To get an error in RxJS subscribe method you have to return such a http response that doesn't have 2xx status code. Based on your code snippet Bad Request (400) could be a good choice for example. So on .NET Core side you need to return an IActionResult following way:
[Route("RegisterPatientInput")]
public IActionResult RegisterGetPaymentDeadlineExtension(PatientInput data)
{
SrvInvoiceCompositView[] list = null;
string ContractNo = String.Empty;
string DktInvoiceNo = String.Empty;
try
{
ContractNo = data.BillNumber.Split('-')[0];
DktInvoiceNo = data.BillNumber.Split('-')[1];
list = DkService.SrvFindInvoiceCompositViewDentaPay(DktInvoiceNo, data.Amount, data.PatientNumber, ContractNo);
return Ok(list); // This is has http status code 200 in the http response
}
catch(Exception ex)
{
return BadRequest(ex.Message); // This has http status code 400 in the http response
}
}
If you put in the Angular Component file following:
this.homePageService.GetPaymentDeadlineExtension(this.input).subscribe(
data=>
{
this.patientInfo = data;
},
error=>
{
console.log(error);
}
)
After a http request you will be able to see the exception message from the backend in the browser console.
I don't know exactly the use case of the developed software, but it is not recommended to display the exception on the frontend side in production. A hacker could extract some information from the server code with causing intentionally exceptions.

Getting 404 in WebSocket connection

I have a backend java code for websocket.
SessionEndpoint:
#ServerEndpoint("/session")
public class SessionEndpoint {
private static Set<SessionEndpoint> sessionEndpoints = new CopyOnWriteArraySet<>();
#OnMessage
public void onMessage(Session session, String sessionId) {
Map<String, Object> attributes = new HashMap<>();
attributes.put("sessionId", sessionId);
sessionEndpoints.forEach(endpoint -> {
synchronized (endpoint) {
try {
session.getBasicRemote().sendObject(attributes);
} catch (IOException | EncodeException e) {
e.printStackTrace();
}
}
});
}
}
Trying to connect to websocket from javascript, code is given below.
let webSocket = new WebSocket('ws://localhost:9999/session');
webSocket.onopen = () => webSocket.send('hello');
webSocket.onmessage = function(response) {
console.log(response);
};
I get 404 response code while connecting to websocket. How should I connect to webscoket from javascript ?

SignalR js client wrong Server port

I'm starting with signalr but got some trouble, my test server run at http://localhost:22660/ and my web run at
http://localhost:61963/.I got this error when connect from client to server:
GET http://localhost:61963/signalr/negotiate?clientProtocol=1.4&connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&_=1496809403215 404 (Not Found)
I already config: $.connection.hub.url = 'http://localhost:22660/signalr'; but not work, this my js code:
var connection = $.hubConnection();
$.connection.hub.url = 'http://localhost:22660/signalr';
var chatHub = connection.createHubProxy('ChatHub');
connection.start()
.done(function () { console.log('Now connected, connection ID=' + connection.id); })
.fail(function () { console.log('Could not connect'); });
Server:
namespace test
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});
}
}
}
namespace SignalRChat
{
public class ChatHub : Hub
{
public void Send(string name, string message)
{
// Call the addNewMessageToPage method to update clients.
Clients.All.addNewMessageToPage(name, message);
}
}
}
I dont sure, but i think because i using different version of signalr (2.1.2 and 2.2.0). Using same version solved my problem.

Categories

Resources