我第一次在javafx项目上使用websockets,当我启动程序时,会话设置为局部变量会话,但是当我调用sendMessage函数之后,会话又回到了null。请在下面找到我的客户类
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);
}
}
有什么建议吗?
提前致谢
我想我现在知道这个问题的答案了。
您可能正在使用tomcat或其他服务器。当您在此答案中看到"tomcat"时,请插入您实际使用的服务器的名称。
当打开与 websocket 的连接时,tomcat 将自行创建 websocket(您的Client
)类的实例。这意味着,将调用onOpen
-Method,看起来好像是您创建了实例,打开了连接,而实际上您没有。雄猫做到了。
这反过来意味着,当您在客户端实例上调用sendMessage
时,会话将被null
,因为此对象从未在任何地方连接过。
哦,您无权访问由 tomcat 创建的已连接实例。
解决此问题的一种方法是在onOpen
-Method 中完成所有工作,但这是不切实际的。您可能希望将工作放在另一个方法中,并从onOpen
调用它。这样,tomcat 创建的实例将完成必要的工作。
在我的项目中,我需要对 MQTT-Topic 进行轮询,并在网站上呈现数据(大学作业)。我在单独的类中进行轮询,导致每当尝试使用我的sendMessage
-方法 发送接收到的数据时,都很难调试错误。
我希望这个答案确实澄清了这一点,如果不是为了你,也许至少是为了拥有相同大学任务的后代......