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 + "'");
}
}
Related
I need to establish connection between client websocket threw my backend on spring java to another websocket where my backend is a client, I established connection as client but can't figure out how to send it back as soon as my client send me message,
My Client Endpoint works as I need
#Service
#ClientEndpoint
public class ClientEndpoint {
Session userSession = null;
private MessageHandler messageHandler;
public WbsClientEndpoint(#Value("${url}") String url) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, new URI(url));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#OnOpen
public void onOpen(Session userSession) {
System.out.println("opening web socket");
this.userSession = userSession;
}
#OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing web socket");
this.userSession = null;
}
#OnMessage
public void onMessage(String message) {
if (this.messageHandler != null) {
this.messageHandler.handleMessage(message);
}
}
public void addMessageHandler(MessageHandler msgHandler) {
this.messageHandler = msgHandler;
}
public void sendMessage(String message) {
this.userSession.getAsyncRemote().sendText(message);
}
public interface MessageHandler {
void handleMessage(String message);
}
}
and example of method when I send my message as client, it does what I need but now I only printing the message cause cannot connect it to my message handler:
#Override
public void addDevice(DeviceTransfer deviceTransfer) {
clientEndPoint.addMessageHandler(message -> {
System.out.println("Response: " + message);
});
clientEndPoint.sendMessage(JSON.toJSONString(deviceTransfer));
}
Also I wrote a websockethandler for messages that comes to my backend:
#Component
public class WebSocketHandler extends AbstractWebSocketHandler {
#Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
System.out.println("New Text Message Received" + message + " ___ " + session);
String clientMessage = message.getPayload();
if (clientMessage.startsWith("/addDevice")) {
//Here I don't know how to send this clientMessage and wait for result from my addDevice method to return it back
}
}
}
And I need to connect both of the realizations to establish connection in real time.
When client sends message to me I must send this message to another server as client.
My client code on JavaScript as example, when I press button it establish connection to my web socket and send my message:
const connectBtn = document.getElementById('connect');
if (connectBtn) {
connectBtn.addEventListener('click', function () {
window.socket1 = new WebSocket("ws://localhost:8081/ws");
socket1.onopen = function(e) {
console.log("[open]");
socket1.send(JSON.stringify({"command": "subscribe","identifier":"{\"channel\":\"/topic/addDevice\"}"}))
};
socket1.onmessage = function(event) {
console.log(`[message]: ${event.data}`);
};
socket1.onclose = function(event) {
if (event.wasClean) {
console.log(`[close],code=${event.code}reason=${event.reason}`);
} else {
console.log('[close]');
}
};
socket1.onerror = function(error) {
console.log(`[error] ${error.message}`);
};
});
}
It seems to me like you need to keep track of your ClientEndpoint instances:
public class ClientEndpoint {
private HashSet<ClientEndpoint> endpoints = new HashSet<>();
// or perhaps a HashMap using `userSession.id` or similar
private HashMap<string, ClientEndpoint> userToEndpoint = new HahsMap<>();
#OnOpen
public void onOpen(Session userSession) {
System.out.println("opening web socket");
this.userSession = userSession;
this.endpoints.add(this);
this.userToEndpoint.put(userSession.id, this);
}
#OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing web socket");
this.endpoints.remove(this);
this.userToEndpoint.delete(userSession.id);
this.userSession = null;
}
}
You can use endpoints/userToEndpoint to find all connected clients, perhaps filter by which rooms they're in (I assume that's what you're trying to accomplish with that subscribe command), and do whatever you want with that information. E.g. a broadcast to everyone except the sender:
for (ClientEnpoint endpoint : this.endpoints) {
if (endpoint == sender) continue; // Don't send to sender
endpoint.sendMessage("message");
}
while signing up, I am unable to get the response code and error message so can you help me?
This is My Interface
public interface SignupAPI {
#FormUrlEncoded
#POST("users")
Call<ResponseBody> createUser(
#Field("email") String email,
#Field("password") String password,
#Field("role") String role
);
}
This is Java Class
public class SignupClient {
private static final String BASE_URL = "http://74.207.233.160/api/v1/";
private static SignupClient mInstance;
private Retrofit retrofit;
private SignupClient(){
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
}
public static synchronized SignupClient getmInstance(){
if (mInstance == null){
mInstance = new SignupClient();
}
return mInstance;
}
public SignupAPI getApi(){
return retrofit.create(SignupAPI.class);
}
}
This Is Signup Activity
progressBar.setVisibility(View.VISIBLE);
Call<ResponseBody> call = SignupClient.getmInstance().getApi().createUser(email, password,role);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()){
progressBar.setVisibility(View.GONE);
Toast.makeText(SignupActivity.this, "Account Sucessfully Created", Toast.LENGTH_SHORT).show();
}else {
try {
progressBar.setVisibility(View.GONE);
JSONObject jsonError = new JSONObject(response.errorBody().string());
Toast.makeText(SignupActivity.this, jsonError.getString("errors"),Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
progressBar.setVisibility(View.GONE);
e.printStackTrace();
} catch (IOException e) {
progressBar.setVisibility(View.GONE);
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(SignupActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
I am not able to get error message and also response code so please help me to get it.
Here is the Postman PostMan API
Here I have written how you can get HTTP code from both success response and error response.
#Override
public void onResponse(Call<T> call, Response<T> response) {
int statusCode = response.code();
}
#Override
public void onFailure(Call<T> call, Throwable t) {
if (new Exception(t) instanceof HttpException) {
int statusCode = ((HttpException) t).getStatusCode();
else {
// unknown error
}
}
I've started this multi chat thread alert system and I've successfully gotten multiple clients on the server, but when broadcasting the message to everyone, it only interacts with the initial client sending the message and the sever only, the other client does not receive the message.
Here are the codes I'm working with
Client 1
package popup;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ClientJFrame extends javax.swing.JFrame {
static Socket s;
static DataInputStream din;
static DataOutputStream dout;
public ClientJFrame() {
super("Client 1");
initComponents();
}
private void alertButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
String msgout = "Alert client 1\n";
dout.writeUTF(msgout);
} catch (Exception e) {
}
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ClientJFrame().setVisible(true);
}
});
try {
s = new Socket("127.0.0.1", 111);
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
String msgin = "";
while (true) {
msgin = din.readUTF();
messageArea.append(msgin);
JOptionPane.showMessageDialog(null, "BITCH WE ON FIRE");
s.close();
System.exit(0);
}
} catch (Exception e) {
}
}
// Variables declaration - do not modify
private javax.swing.JButton alertButton;
private javax.swing.JScrollPane jScrollPane1;
private static javax.swing.JTextArea messageArea;
// End of variables declaration
}
Server
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class TestJFrame extends javax.swing.JFrame {
static ServerSocket listener;
static Socket s;
private static final int PORT = 111;
public TestJFrame() {
super("Main");
initComponents();
}
public static class Handler extends Thread {
private final Socket socket;
private DataInputStream in;
private DataOutputStream out;
public Handler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
in = new DataInputStream(socket.getInputStream());
messageArea.append("in\n");
out = new DataOutputStream(socket.getOutputStream());
messageArea.append("Out\n");
} catch (IOException e) {
}
while (true) {
try {
String input = in.readUTF();
messageArea.append(input);
out.writeUTF("We on Fire!!!\n");
} catch (IOException ex) {
Logger.getLogger(TestJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public static void main(String args[]) throws IOException, InterruptedException {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new TestJFrame().setVisible(false);
createAndShowGUI();
}
});
listener = new ServerSocket(PORT);
try {
while (true) {
new Handler(listener.accept()).start();
}
} finally {
listener.close();
}
}
// Variables declaration - do not modify
private javax.swing.JButton alertButton;
private javax.swing.JScrollPane jScrollPane1;
private static javax.swing.JTextArea messageArea;
// End of variables declaration
}
When a client connects to the server, add him to a list, so you always know who's connected. The same goes for when he disconnects.
When a client sends a message, process it however you want, then iterate over the list of connected clients and send them the message.
Take a look at the observer pattern, I think it will help for your project.
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
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?