My IDE : NetBeans, GlassFish.
I am trying to understand how GlassFish execute and run the Endpoint!
I understand Glassfish as a webserver creates new Endpoint instance for each connection, and the Set : peers in the code appears as one global variable for every instance of endpoint.
My question is : how to add another global variable(s) so every instance of endpoint can access it?
enter code here
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
#ServerEndpoint("/echo")
public class EchoServer {
/**
* #OnOpen allows us to intercept the creation of a new session.
* The session class allows us to send data to the user.
* In the method onOpen, we'll let the user know that the handshake was
* successful.
*/
private static final Set<Session > peers = Collections.synchronizedSet(new HashSet<Session >());
#OnOpen
public void onOpen(Session session){
System.out.println(session.getId() + " has opened a connection");
try {
peers.add(session);
session.getBasicRemote().sendText("Connection Established");
} catch (IOException ex) {
ex.printStackTrace();
}
}
#OnMessage
public void onMessage(String message, Session session) throws IOException{
System.out.println("Message from " + session.getId() + ": " + message);
for (Session peer : peers) {
peer.aplayer.getBasicRemote().sendText(" Message from " + session.getId()+" : "+message);
}
}`enter code here`
#OnClose
public void onClose(Session session){
System.out.println("Session " +session.getId()+" has ended");
peers.remove(session);
}
}
Related
I am currently trying to get the finnhub websocket to run via Java. The connection is also established, but I immediately get a closed message from the connection before I even get a message. Here my code:
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
import jakarta.websocket.ClientEndpoint;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
#ClientEndpoint
public class FinnhubQuoteWebsocket {
private static CountDownLatch latch;
private static final String API_KEY = "YOUR_KEY";
public static void main(String[] args) throws Exception {
String endpoint = "wss://finnhub.io/ws?token="
+ API_KEY;
latch = new CountDownLatch(1);
URI uri = new URI(endpoint);
FinnhubQuoteWebsocket client = new FinnhubQuoteWebsocket();
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(client,
uri);
latch.await();
}
#OnClose
public void onClose(Session session) {
System.out.println("###Close###");
}
#OnMessage
public void onMessage(Session session,
String message) {
System.out.println("Received quote message: "
+ message);
latch.countDown();
}
#OnOpen
public void onOpen(Session session) throws IOException {
String subscribeSymbolAAPL = "{\"type\":\"subscribe\",\"symbol\":\"AAPL\"}";
System.out.println("Connected to websocket: "
+ session.getBasicRemote());
System.out.println("Json: "
+ subscribeSymbolAAPL);
session.getBasicRemote().sendText(subscribeSymbolAAPL);
}
}
Consolen Output:
Connected to websocket: Wrapped: Basic
Json: {"type":"subscribe","symbol":"AAPL"}
###Close###
I do not know what I'm doing wrong. Presumably the connection has to be open longer for a message to come?
I tried various examples from Google and ChatGpt. But always the same problem that the connection is immediately closed again.
I hope someone can tell me what I'm doing wrong.
I have the following simple websocket example:
package com.bfaconsultora.rest.europa.resources;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.OnOpen;
import javax.websocket.OnMessage;
import javax.websocket.OnClose;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.DefaultValue;
#ServerEndpoint("/api/europa/qr/websocket")
public class QrWebSocket {
private Set<Session> sessions = new HashSet<>();
#OnOpen
public void onOpen (
Session session
) {
sessions.add(session);
}
#OnMessage
public void handleMessage(String message, Session session) {
try {
for (int c = 0; c < 100; c++) {
for (Session s : sessions) {
s.getBasicRemote().sendText("{\"value\" : \"" + (c + 1) + "\"}");
}
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#OnClose
public void onClose(Session session) {
sessions.remove(session);
}
}
running on Apache Tomcat 9.
Is it possible to access header params (I need it for authentication purposes)? Could you please point me the right direction?
Thank you in advance.
Regards
It's not possible (or at last not a common practice) to read header params from a web socket. The usual way to authenticate is to send auth information in the first message, but there are other ways.
I found this reading very useful.
Regards to everyone.
I am using websockets for the first time on a javafx project, when I start the program the session is set to the local variable session, but after when I call the sendMessage function the session is back to null. Below please find my client class
package myclient;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javax.websocket.ClientEndpoint;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
#ClientEndpoint
public class Client extends Application {
private static final Logger LOGGER = Logger.getLogger(Client.class.getName());
private Session session;
#OnOpen
public void onOpen(Session session){
this.session = session;
System.out.println("Opened Session " + this.session);
}
#OnClose
public void onClose(){
System.out.println("Closed Session " + this.session);
}
#OnMessage
public void onMessage(String msg){
System.out.println("Websocket message received! " + msg);
}
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLClient.fxml"));
Scene scene = new Scene(root);
connectToWebSocket();
stage.setScene(scene);
stage.show();
}
private void connectToWebSocket() {
System.out.println("Client WebSocket initialized>> " + this.session);
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
try {
URI uri = URI.create("ws://localhost:8080/Server/endpoint");
container.connectToServer(this, uri);
}
catch (DeploymentException | IOException ex) {
LOGGER.log(Level.SEVERE, null, ex);
System.exit(-1);
}
}
public void sendMessage(String message) throws IOException{
if(this.session != null){
System.out.println(message + ", " + this.session);
this.session.getBasicRemote().sendText(message);
}
else {
System.out.println("Session is null");
}
}
public static void main(String[] args) {
launch(args);
}
}
Any suggestions?
Thanks in advance
I think I now do know the answer to this.
You are probably using tomcat or some other server for this. When you see "tomcat" in this answer, please insert the name of your actually used server.
When a connection to your websocket is opened, tomcat will create an instance of the websocket (your Client) class by itself. This means, the onOpen-Method will be called and it will look as if it was you who created the instance, who opened the connection, when really you did not. Tomcat did.
This in turn means, that when you call sendMessage on your Client instance, the session will be null, because this object never connected anywhere.
Oh, and you don't have access to the connected instance that was created by tomcat.
One way of fixing this would be to do all the work inside the onOpen-Method, however that is not practical. You may want to put the work in another method and call it from onOpen. That way, the instance created by tomcat will do the necessary work.
In my project I needed to poll on an MQTT-Topic and render the data on a website (university assignment). I did the polling in a separate class, resulting in hard to debug errors whenever trying to send received data with my sendMessage-method.
I hope this answer does clear this up a little, if not for you, maybe at least for future generations having the same university assignment...
The WebSocket is working perfectly in localhost (tomcat) . but when i host (Openshift - tomcat) it immediately disconnects and not firing the onMessage method. I've checked the header and the status code is Status Code:101 Switching Protocols.
Here is my socket.
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
#ServerEndpoint("/TestSocket")
public class TestSocket {
#OnOpen
public void onOpen(Session session) {
try {
session.getBasicRemote().sendText("Connected");
} catch (IOException e) {
e.printStackTrace();
}
}
#OnMessage
public void onMessage(Session session, String message) {
System.out.println("New message : " + message);
try {
session.getBasicRemote().sendText("Message received -> :" + message);
} catch (IOException e) {
e.printStackTrace();
}
}
#OnClose
public void onClose() {
System.out.println("Closed");
}
}
Here is the live socket ws://shifar-shifz.rhcloud.com:8000/MyTestProject/testWebSocket. I can't figure out what the problem is. Please help me.
EDIT
I am using the Tomcat 7 (JBoss EWS 2.0) cartridge. The project was deployed through a WAR file.
I found it's working when i remove the web-socket-api.jar from the lib after the artifact building. I think the Openshift already contain another web-socket-api.jar in their server. and can't contain any duplicate of the existing jars/libs.
I have the following clientendpoint class for a websocket in tomcat 7.0.53. It is based off of this example on a website https://blog.openshift.com/how-to-build-java-websocket-applications-using-the-jsr-356-api/
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
#ClientEndpoint
public class connect {
private static ArrayList<Session> sessionList = new ArrayList<Session>();
public connect(URI endpointURI) throws DeploymentException, IOException
{
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
}
#OnOpen
public void onOpen(Session session) throws IOException
{
sessionList.add(session);
System.out.println(session.getId());
session.getBasicRemote().sendText("hello");
}
public void sendMessage(String message) throws IOException
{
for(Session session : sessionList){
//asynchronous communication
session.getBasicRemote().sendText(message);
}
}
#OnClose
public void onClose(Session session){
sessionList.remove(session);
System.out.println("here");
}
#OnError
public void onError(Throwable t, Session session){
System.out.println("tedt");
}
}
I then have the following code to start the client endpoint
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.websocket.DeploymentException;
public class test {
public static void main(String[] args) throws DeploymentException, IOException, URISyntaxException {
// TODO Auto-generated method stub
connect connect = new connect(new URI("ws://localhost:8080/example/talk"));
connect.sendMessage("now");
}
}
The client does successfully connect to the websocket server, however then it gets disconnected right away when I try to send a message or do anything, I know this since the onError function is being called when I try to send a message from the onOpen function. Why is the websocket getting closed immediately after it is connected to the server?
You are being disconnected because your main thread in your client application is ending. After you send "now", your program simply exits. If you want to do anything else (like wait for a response from the server, for instance), then you'll have to prevent the main thread from exiting. Try something like this at the end of your main method:
System.in.read();
This will cause your process to sit and wait for input from standard input. Simply wait for your test to complete and then press ENTER on the command-line to terminate the client.
You will, of course, want to register a handler for receiving messages back from the server to the client. Right now, you can only send messages from the client to the server.