How can i use socket communication between java server and javascript client? - javascript

I'm trying to connect java Server and Javascript client with socket.io. When i see the debugger at browser, it looks like the data is being received, but i'm getting this error: "Reason: CORS header 'Access-Control-Allow-Origin' missing" and i am not being able to print data at client-side.
import...
public class MeuServerSocket {
//initialize socket and input stream
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream in = null;
public MeuServerSocket(int port) {
// starts server and waits for a connection
try {
while(true){
server = new ServerSocket(port);
System.out.println("Server started");
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted");
ObjectOutputStream saida = new ObjectOutputStream(socket.getOutputStream());
saida.flush();
// send available data from server to client
saida.writeObject("Texto enviado 123...");
// takes input from the client socket
in = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
String line = "";
// reads message from client until "Over" is sent
boolean fim = false;
while (!line.equals("Over") && !fim)
{
try
{
line = in.readUTF();
System.out.println(line);
}
catch(IOException i)
{
fim = true;
System.out.println(i.toString());
}
}
System.out.println("Closing connection");
// close connection
socket.close();
saida.close();
in.close();
}
} catch (IOException i) {
System.out.println(i);
}catch(Exception e){
System.out.println(e.toString());
}
}
public static void main(String[] args) {
MeuServerSocket server = new MeuServerSocket(5000);
}
}
var socket = io('http://localhost:5000');
socket.on('connect', function () {
socket.send('hi \nOver');
socket.on('get', function (msg) {
// my msg
console.log('msg: '+msg)
})
socket.on('disconnect',()=>{
console.log('disconnected')
})
})
When i look at Firefox network, i see that the data was sent inside one of the packages...
https://imgur.com/vDAS00B

The biggest issue I'm seeing here is a misunderstanding of socket.io. Socket.io for javascript is not compatible with the Socket library in java. The naming conventions can be confusing for sure.
socket.io is a library that is related to web sockets (ws://). It implements all the basic websocket features plus some bonuses.
What you have for your java code is a TCP socket server. While websockets and socket.io are built on TCP socket, you can not connect a socket.io client to a "naked" socket server.
SOLUTION:
If your javascript is running from nodejs, you can use their net library found here. If you are running javascript from a webbrowser, than you are limited to websockets, which means you're going to change your java code to a websocket server. You can find a library for that somewhere online.

TLDR: Use ws://... instead of http://....
Details:
https is used for HTTP protocol. In such case it is correct that browser first asks your server if CORS is allowed. You have not enabled CORS. That's why it is normal that browser refuses to send CORS request.
But you say you want to use Web Sockets. Then you should use ws://, not http://. For Web Sockets there is no CORS policy and browser will send your request without CORS restrictions.

Related

How can I send data to a specific socket?

My problem is that the current solution I have for sending a specific socket using the library "ws" with node.js is not good enough.
The reason is because if I connect with multiple tabs to the websocket server with the same userid which is defined on the client-side, it will only refer to the latest connection with the userid specified.
This is my code:
// Server libraries and configuration
var server = require("ws").Server;
var s = new server({ port: 5001});
// An array which I keep all websockets clients
var search = {};
s.on("connection", function(ws, req) {
ws.on("message", function(message){
// Here the server process the user information given from the client
message = JSON.parse(message);
if(message.type == "userinfo"){
ws.personName = message.data;
ws.id = message.id;
// Defining variable pointing to the unique socket
search[ws.id] = ws;
return;
}
})
})
As you can see, each time a socket with same id connects, it will refer to the latest one.
Example If you did not understand:
Client connect to server with ID: 1337
search[1337] defined as --> websocket 1
A new connection with same ID: 1337
search[1337] becomes instead a variable refering to websocket 2 instead
Websockets provide a means to create a low-latency network "socket" between a browser and a server.
Note that the client here is the browser, not a tab on a browser.
If you need to manage multiple user sessions between the browser and server, you'll need to write code to do it yourself.

WCF Full Duplex Application with Websocket Client

We had created WCF web service with one method. Service is hosted on external server i.e. Windows Server 2012 and IIS 8.0.
WCF Service URL: http://184.106.9.214/WCFReportingService/Service1.svc
WCF method:
public void ProcessReport()
{
for (int i = 1; i <= 100; i++)
{
// some logic to process the report
Thread.Sleep(100);
// Get the callback channel to send messages to the client
OperationContext.Current.
GetCallbackChannel<IReportServiceCallback>().Progress(i);
}
}
We are trying to create client using HTML5 and JavaScript. Below is the logic we used to initiate the connection.
ws = new WebSocket("ws://localhost/WCFReportService/Service1.svc");
alert(ws);
ws.onopen = function () {
// Web Socket is connected, send data using send()
ws.send("Message to send");
alert("Message is sent...");
$("#spanStatus").text("connected");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
alert("Message is received...");
$("#spanStatus").text(evt.data);
};
ws.onerror = function (evt) {
$("#spanStatus").text(evt.message);
};
ws.onclose = function () {
// websocket is closed.
alert("Connection is closed...");
$("#spanStatus").text("disconnected");
};
We were not able to establish the connection to server. We are thinking that it might be something to do with client side web.config file. But we are not sure how to implement or build connection.
Can anyone help us to build client-server connection?
Thanks.
It might help someone with similar problem I had. Below are the links I used and I was able to get it working.
Introduction 2 : http://www.codeproject.com/Articles/618032/Using-WebSocket-in-NET-4-5-Part-2
Introduction 3 : http://www.codeproject.com/Articles/619343/Using-WebSocket-in-NET-4-5-Part-3

How do I connect to a local Android Server from a Chromecast?

What I am trying to do is start a local server on my Android Device and from a Chromecast connect to the Android Server so that I can send image data from the android to a Chromecast.
What I've done so far is set up a ServerSocket on the Android that is binded to the 127.0.0.1 and then send the localhost information (port number) in a message to the chromecast which tells it the serversocket is ready to accept connections and instructs the Chromecast to connect to the server. But I have no idea how I should be connecting to it. I've tried using WebSockets to connect to the ServerSocket but I'm getting
WebSocket connection to 'ws://localhost:9147/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
I've changed the port number, tried both "ws" and "wss" and I've tried searching for the answer but everything I've come across has been "how to connect android to a server" or "how to connect an Android server to an Android client" so I appologize if this is a repost.
What I was planning on doing is using Base64 image encoding to send a String with the image data to the chromecast and then set the image src to that. I obviously not want to do this using Cast.CastAPI.sendMessage().
To be clear, I am looking for a way to connect to an Android server using JavaScript.
The Android code runs fine, the Chromecast gets the message but when it tries to connect it fails.
Android Code:
Runnable bitmapSender = new Runnable() {
private ServerSocket serverSocket;
public static final int SERVERPORT = 9147;
#Override
public void run() {
Socket socket = null;
try {
Log.d(TAG, "Socket binding attempt");
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(SERVERPORT));
String message = createJsonMessage(MessageType.socket, "wss://localhost:"+ SERVERPORT);
sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
Log.d(TAG, "Socket thread");
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
BitmapExecutorService.execute(commThread);
}catch(IOException e){
e.printStackTrace();
}
}
}
};
Javascript:
function connectToSocket(source){
//Connect to socket
window.socket = new WebSocket(source);
socket.onopen = function() {
socket.send('Hello Android');
};
window.socket.onmessage = function(event) {
console.log('Received a message from the server!', data);
var jsonObj = JSON.parse(event.data)
if(jsonObj.type == "image"){
console.log('Image sent :)');
var source = 'data:image/png;base64,'.concat(jsonObj.data)
displayEncodedImage(source);
}
};
Thanks
edit: Update
I was trying to connect through localhost. This didn't work like I thought it would. I still haven't got the image sending working but I now have the handshake. What I needed to do was send the IP Address of the phone. I did so by adding the ACCESS_WIFI_STATE permission to the manifest and obtaining the IP Address with the following code:
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

Listening websocket in MVC

I'm using MVC 4. I have a js code that needs to communicate with the server with the help of Websockets. I'm using Fleck at the server. I'm creating the socket server in Application_Start event. But when I try the connection from browser console, I get errors like Connection refused.
Here is my global.asax code.
protected void Application_Start()
{
IPAddress ip = null;
if (GetResolvedConnecionIPAddress(out ip)) // Get host ip
{
string Domain = "wss" + System.Uri.SchemeDelimiter + ip + ":" + "8092";
FleckLog.Level = Fleck.LogLevel.Debug;
try
{
if (GetResolvedConnecionIPAddress(out ip))
{
var server = new WebSocketServer(Domain);
server.Start(socket =>
{
LogWriter.Logger.Info("WS: Inside socket server");
socket.OnOpen = () =>
{
LogWriter.Logger.Info("WS: OnOpen socket");
};
socket.OnClose = () =>
{
LogWriter.Logger.Info("WS: OnClose socket");
};
socket.OnMessage = message =>
{
LogWriter.Logger.Info("WS: OnMsg socket");
};
});
}
}
catch (Exception e)
{
throw;
}
}
}
It looks like as soon as the Application_Start method ends, that WebSocketServer is going to get out of scope and eventually garbage collected.
You could, set that object as member in the Global class, and dispose it on the Application_End event for example.
UPDATE:
You are also using the wss schema but not providing any certificate configuration. Please note that IIS and Fleck are two different things, that runs in different ports, and not because you create Fleck into the ASP.NET app means that Fleck is going to infer the SSL/TLS configuration or any configuration at all. Try to set the schema to ws instead and open the page without HTTPS and see if it works.

Can I broadcast to all WebSocket clients

I'm assuming this isn't possible, but wanted to ask in case it is. If I want to provide a status information web page, I want to use WebSockets to push the data from the server to the browser. But my concerns are the effect a large number of browsers will have on the server. Can I broadcast to all clients rather than send discrete messages to each client?
WebSockets uses TCP, which is point to point, and provides no broadcast support.
Not sure how is your client/server setup, but you can always just keep in the server a collection of all connected clients - and then iterate over each one and send the message.
A simple example using Node's Websocket library:
Server code
var WebSocketServer = require('websocket').server;
var clients = [];
var socket = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
socket.on('request', function(request) {
var connection = request.accept('any-protocol', request.origin);
clients.push(connection);
connection.on('message', function(message) {
//broadcast the message to all the clients
clients.forEach(function(client) {
client.send(message.utf8Data);
});
});
});
As noted in other answers, WebSockets don't support multicast, but it looks like the 'ws' module maintains a list of connected clients for you, so it's pretty easy to iterate through them. From the docs:
const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ port: 8080 });
wss.broadcast = function(data) {
wss.clients.forEach(client => client.send(data));
};
Yes, it is possible to broadcast messages to multiple clients.
In Java,
#OnMessage
public void onMessage(String m, Session s) throws IOException {
for (Session session : s.getOpenSessions()) {
session.getBasicRemote().sendText(m);
}
}
and here it is explained.
https://blogs.oracle.com/PavelBucek/entry/optimized_websocket_broadcast.
It depends on the server-side really. Here's an example of how it's done using Tomcat7:
Tomcat 7 Chat Websockets Servlet Example
and an explanation of the how it's constructed here.
Yes you can and there are many socket servers out there written in various scripting languages that are doing it.
The Microsoft.Web.WebSockets namespace has a WebSocketCollection with Broadcast capability. Look for the assembly in Nuget. The name is Microsoft.WebSockets.

Categories

Resources