I would like to send JSON data from a Java Application to a JavaScript. The JSON is log/statistical data which I would like to format with JavaScript and view in the browser in realtime.
I tried it through a Socket but JavaScript's WebSocket does not really accept the Socket from Java. Firefox tells me that it can't establish an connection to ws://localhost:8000.
Java Socket
ServerSocket serverSocket = new ServerSocket(8000);
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("Message");
JavaScript WebSocket
var exampleSocket = new WebSocket("ws://localhost:8000");
exampleSocket.onmessage = function (event) {
console.log(event.data);
};
If this is not possible because of incompatability. What would be the simplest way to send JSON to JavaScript?
There actually is a WebSocket implementation for Java:
http://www.html5rocks.com/en/tutorials/websockets/basics/
Then under Server Side Implementations > Java > Jetty
http://www.eclipse.org/jetty/
Related
So I am trying to setup a client websocket in a Javascript file talking to a server written in C#.
Client:
var socket = new WebSocket("ws://localhost:11000");
function barf() {
socket.send('asdf');
}
socket.onmessage = function(e){
console.log(e.data);
};
Server:
IPHostEntry ipHostInfo = Dns.GetHostEntry("localhost");
IPAddress ipAddress = ipHostInfo.AddressList[1];
TcpListener listener = new TcpListener(ipAddress, 11000);
try
{
listener.Start();
TcpClient client = listener.AcceptTcpClient();
message = client.GetStream();
int i = message.Read(bytes);
string data = Encoding.ASCII.GetString(bytes, 0, i);
string key = new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim();
Byte[] response = GetHandshakeResponse(key);
message.Write(response, 0, response.Length);
bytes = new Byte[1024];
i = message.Read(bytes);
Console.WriteLine(Encoding.ASCII.GetString(bytes));
}
The issue is that when I call the function 'barf' in my Javascript file, the server spits out a different message each time as if it were being encrypted. I have tried using different encodings and I can't seem to end up with exactly 'asdf' on the server. Does anyone have any insight? Thanks!
If you want to encrypt communication over web sockets, use the wss protocol instead of ws.
Also, I don't think your test is meaningful, because you haven't run it with a server socket server on the back end.
Creating a "Hello World" WebSocket example
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.
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
What are my options for converting a socketio nodejs application to dart? Is there support for nodejs servers using dart somehow (ideally with all the fancy debugging capabilities of the dart editor)? Does socketio have a dart based library?
Dart has a server side VM, just like V8 has a server side VM in the form of node.js.
Take a look at Adam Smith's webserver chat sample, which uses websockets on the server side to communicate with websockets on the client side, with both parts being written in Dart.
The key parts for the server side look like:
import "dart:io";
main() {
HttpServer server = new HttpServer();
WebSocketHandler wsHandler = new WebSocketHandler();
server.addRequestHandler((req) => req.path == "/ws", wsHandler.onRequest);
wsHandler.onOpen = (WebSocketConnection conn) {
conn.onMessage = (message) {
print(message);
conn.send("hello, this is the server");
};
};
server.listen("127.0.0.1",8080);
}
Then on the client, something like
import "dart:html";
main() {
var ws = new WebSocket("ws://127.0.0.1:8080/ws");
ws.on.open.add( (a) {
ws.send("hello, this is the client");
});
ws.on.message.add( (messsage) {
print(message);
});
}
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.