When I try to connect node.js from java socket.io client I'm getting this error:
engine intercepting request for path "/socket.io/" +0ms
engine handling "GET" http request "/socket.io/1/" +0ms
engine unknown transport "undefined" +0ms
Meantime, when I try from a javascript client, works fine:
engine intercepting request for path "/socket.io/" +0ms
engine handling "GET" http request "/socket.io/?EIO=3&transport=polling&t=1494940689150-0&b64=1" +0ms
engine handshaking client "3EFWO3PTlnvZksM8AAAA" +15ms
My Java client code:
import io.socket.IOAcknowledge;
import io.socket.IOCallback;
import io.socket.SocketIO;
import io.socket.SocketIOException;
import org.json.JSONException;
import org.json.JSONObject;
public class BasicExample implements IOCallback {
private SocketIO socket;
public static void main(String[] args) {
try {
new BasicExample();
} catch (Exception e) {
e.printStackTrace();
}
}
public BasicExample() throws Exception {
socket = new SocketIO();
socket.connect("http://localhost:9990", this);
socket.send("Hello Server");
// Sends a JSON object to the server.
socket.send(new JSONObject().put("key", "value").put("key2","another value"));
// Emits an event to the server.
socket.emit("event", "argument1", "argument2", 13.37);
}
#Override
public void onMessage(JSONObject json, IOAcknowledge ack) {
try {
System.out.println("Server said:" + json.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onMessage(String data, IOAcknowledge ack) {
System.out.println("Server said: " + data);
}
#Override
public void onError(SocketIOException socketIOException) {
System.out.println("an Error occured");
socketIOException.printStackTrace();
}
#Override
public void onDisconnect() {
System.out.println("Connection terminated.");
}
#Override
public void onConnect() {
System.out.println("Connection established");
}
#Override
public void on(String event, IOAcknowledge ack, Object... args) {
System.out.println("Server triggered event '" + event + "'");
}
}
In Java, I'm using socketio.jar downloaded from here http://www.java2s.com/Code/Jar/s/Downloadsocketiojar.htm, wich seems was compiled from here https://github.com/Gottox/socket.io-java-client
In node.js server I'm user socket.io#1.0.6 version.
Please, can someone help me?
This client looks to be outdated about 5 years. It seems this is a newer one: https://github.com/socketio/socket.io-client-java
Related
I have websocket in one of my webapplication used to populate the notification
message.
The entire application is a ear file and we have multipe war file in it and this websocket endpoint is one war file.
It contains below:
#ServerEndpoint(value = "/message", configurator = WebSocketConfigurator.class)
public class WebsocketEndpoint {
#OnOpen
public void onOpen(Session session){
}
#OnClose
public void onClose() {
}
#OnError
public void error(Session session, Throwable throwable) {
}
#OnMessage
public void handleMessage(String message, final Session session) {
synchronized (session) {
if (session != null && session.isOpen()) {
int count = 2;
session.getAsyncRemote().sendText("" + count);
session.setMaxIdleTimeout(-1);
}
}
}
}
public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {
private boolean isValidHost;
#Override
public boolean checkOrigin(String originHeaderValue) {
try {
URL url = new URL(originHeaderValue);
String hostName = url.getHost();
isValidHost = Utils.isValidHostName(hostName);
} catch (Exception ex){
logger.error("Error in check checkOrigin for websocket call: "+ex.getMessage());
}
return isValidHost;
}
}
I am calling the endpoint in first login where handshake will happen and get the message and then in every 2 mins it will call to get the message only no handshake since handshake is already there
ui is as below:
var websocketUrl = new WebSocket("ws://localhost:7001/example/message");
webSocket.onopen = function() {
webSocket.send('');
}
var interval= setInterval(function() {
'pollMessage()'
}, 120*1000);
function pollMessage(){
if(wsEndPoint.readyState==1){
wsEndPoint.send('');
}
if(wsEndPoint.readyState ==2 || wsEndPoint.readyState==3){
wsEndPoint.close();
clearInterval(interval);
}
wsEndPoint.onmessage = function(message){
alert(message);
}
}
#WebServlet(urlPatterns = {"/message"})
public class MessageWebsocketServlet extends HttpServlet
{
}
The above works fine without any issue.
But I want to authenticate the call for security.
So I added webfilter
#WebFilter(urlPatterns = {"/message"}, filterName = "AuthFilter",initParams = {
#WebInitParam(name = "authorizationEnabled", value = "false")
})
#ServletSecurity(httpMethodConstraints = {#HttpMethodConstraint(value = "GET")})
public class MessageWebsocketServletFilter implements Filter{
private FilterConfig config = null;
#Override
public void init(FilterConfig config) throws ServletException {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain)
throws ServletException, IOException {
//authentication logic goes here and it involved cross origin check and
}
#Override
public void destroy() {
config.getServletContext().log("Destroying SessionCheckerFilter");
}
}
We have configured 30 mins as session timeout and After adding the above filter when the user logged in and idle more than 30 mins the applicaiton is not getting session timed out.
Any pointer would be great help for me.
Short version:
From what I can see, it is because of the line session.setMaxIdleTimeout(-1);
Long version:
When opening a websocket connection, the client proceeds to a handshake. Following the websocket bible (RFC 6455 section 1.3), the handshake starts with a HTTP communication.
However, once the handshake is successful, the communication switches to another protocol as stated:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
The communication is not HTTP anymore. As far as I know, Java Servlet only handles HTTP communication. Consequently, any configuration regarding the servlet has no impact on the websocket configuration.
I'm trying to write a JavaScript server running on node.js using Socket.io that communicates with the client which is written in JAVA.
I have no problem with the server side because I try it with a JavaScript client, so I assumed that the problem came from my java client.
I have this error on my client side :
io.socket.SocketIOException: Error while handshaking
at io.socket.IOConnection.handshake(IOConnection.java:322)
at io.socket.IOConnection.access$600(IOConnection.java:39)
at io.socket.IOConnection$ConnectThread.run(IOConnection.java:199)
Caused by: java.io.IOException: Server returned HTTP response code: 400 for
URL: http://localhost:8000/socket.io/1/
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown
Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
Source)
at io.socket.IOConnection.handshake(IOConnection.java:313)
This is my code :
public class BasicExample implements IOCallback {
private SocketIO socket;
public static void main(String[] args) {
try {
new BasicExample();
} catch (Exception e) {
e.printStackTrace();
}
}
public BasicExample() throws Exception {
socket = new SocketIO();
socket.connect("http://localhost:8000", this);
// Sends a string to the server.
socket.send("Hello Server");
// Emits an event to the server.
socket.emit("event", "ILYES");
}
#Override
public void onMessage(JSONObject json, IOAcknowledge ack) {
try {
System.out.println("Server said:" + json.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onMessage(String data, IOAcknowledge ack) {
System.out.println("Server said: " + data);
}
#Override
public void onError(SocketIOException socketIOException) {
System.out.println("an Error occured");
socketIOException.printStackTrace();
}
#Override
public void onDisconnect() {
System.out.println("Connection terminated.");
}
#Override
public void onConnect() {
System.out.println("Connection established");
}
#Override
public void on(String event, IOAcknowledge ack, Object... args) {
System.out.println("Server triggered event '" + event + "'");
}
}
I'm trying to do a connection between a server in Java and a JavaScript client but I'm getting this error on client side:
WebSocket connection to 'ws://127.0.0.1:4444/' failed: Connection closed before receiving a handshake response
It maybe stays on OPENNING state because the connection.onopen function is never called. The console.log('Connected!') isn't being called.
Could someone let me know what is going wrong here?
Server
import java.io.IOException;
import java.net.ServerSocket;
public class Server {
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(4444)) {
GameProtocol gp = new GameProtocol();
ServerThread player= new ServerThread(serverSocket.accept(), gp);
player.start();
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
}
}
ServerThread
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread{
private Socket socket = null;
private GameProtocol gp;
public ServerThread(Socket socket, GameProtocol gp) {
super("ServerThread");
this.socket = socket;
this.gp = gp;
}
public void run() {
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
String inputLine, outputLine;
while ((inputLine = in.readLine()) != null) {
outputLine = gp.processInput(inputLine);
System.out.println(outputLine);
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
GameProtocol
public class GameProtocol {
public String processInput(String theInput) {
String theOutput = null;
theOutput = theInput;
return theOutput;
}
}
Client
var connection = new WebSocket('ws://127.0.0.1:4444');
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);
};
To start with, both your code looks identical the Java and JavaScript one. Both work for what they are design to, but the facts is that you are trying to connect a WebSocket client to a socket server.
As I know they are two different things regarding this answer.
I have never tried it your way. That said if I have a network application that use socket than it would be pure client/server socket, and if it was a web application than I would use WebSocket on both side as well.
So far so good..
To make this work, this answer suggests to use any available WebSocket on server side and your problem is solved.
I am using WebSocket for Java and here is a sample implementation that I have tested with your client code and it works, both on client and server side.
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 = 4444;
private Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(TCP_PORT));
conns = new HashSet<>();
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
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(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());
}
}
On your main method just:
new WebsocketServer().start();
You might need to manipulate your code to fit it with this implementation, but that should be part of the job.
Here is the test output with 2 tests:
New connection from 127.0.0.1
Message from client: Ping
Closed connection to 127.0.0.1
New connection from 127.0.0.1
Message from client: Ping
here is WebSocket maven configuration, otherwise download the JAR file/s manually and import it in your IDE/development environment:
<!-- https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket -->
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.0</version>
</dependency>
Link to WebSocket.
I'm doing a websocket with javax.websocket and a JavaScript client; when I call the websocket in JavaScript with a private IP it works, like this:
var websocket = new WebSocket("ws://10.3.3.25:8083/MyJavaWebSocket/MyEndPoint");
But when I try to change the IP for a public IP, it doesn't work:
var websocket = new WebSocket("ws://190.168.10.10:8083/MyJavaWebSocket/MyEndPoint");
or
var websocket = new WebSocket("ws://mydomain.com:8083/MyJavaWebSocket/MyEndPoint");
It throws "failed: Error during WebSocket handshake: Unexpected response code: 404".
This is my Java server code:
#ServerEndpoint(value = "/MyEndPoint", configurator = ChatServerEndPointConfigurator.class)
public class MyEndPoint {
static Set<Session> sesionesUsuarios = Collections.synchronizedSet(new HashSet<Session>());
#OnOpen
public void onOpen(Session session) {
sesionesUsuarios.add(session);
System.out.println(session.getId() + " has opened a connection");
try {
session.getBasicRemote().sendText("Connection Established");
} catch (IOException ex) {
ex.printStackTrace();
}
}
#OnMessage
public void onMessage(String message, Session session) {
session.getBasicRemote().sendText("SEND MESSAGE");
}
#OnClose
public void onClose(Session session) {
sesionesUsuarios.remove(session);
System.out.println("Session " + session.getId() + " has ended");
}
#OnError
public void onError(Throwable e) {
e.printStackTrace();
}
}
I'm using apache-tomcat-8.0.33. Can anyone help shed some light on what is wrong here?
Given a websocket configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/queue", "/topic");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/add").withSockJS();
}
}
and client javascript:
<script type="text/javascript">
console.log('begin javascript');
var stompClient = null;
function connect() {
var socket = new SockJS('/myapp/add');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected to STOMP: ' + frame);
stompClient.subscribe('/user/topic/abc', function(calResult) {
console.log('*** Got it ***');
});
});
}
connect();
</script>
and sending this message from the server:
messagingTemplate.convertAndSendToUser(username, "/topic/abc", "hello");
the callback never gets fired.
The javascript console shows that the connection is made:
Connected to STOMP: CONNECTED user-name:jschmoe heart-beat:0,0
version:1.1
SUBSCRIBE id:sub-0 destination:/user/topic/abc
and the tomcat console shows:
Processing SUBSCRIBE destination=/topic/abc-useryl3ovhr2
subscriptionId=sub-0 session=yl3ovhr2 user=jschmoe payload=byte[0]
and then when the message is sent:
Processing MESSAGE destination=/topic/abc-useryl3ovhr2 session=null
payload=hello
Seems like everything works except for the callback.
In my case the problem was caused by XML configuration, once I switched to Java config with #EnableWebSocketMessageBroker annotation I received the messages on client side.