英文:
JSR-356 websocket - cannot get return code after stopping container
问题
我已经使用 *javax websockets* 构建了一个客户端服务器应用程序。尽管 JSR 356 没有停止 WebSocket 容器的方法,但我成功地在将其转换为 *jetty Lifecycle* 后停止了容器。一旦停止了容器,我就写下了以下代码:
> System.exit(1);
但是从客户端程序返回的代码始终为零。
代码:
@ClientEndpoint
public boolean close() {
try {
if (this.container != null && this.container instanceof LifeCycle) {
logger.trace("停止容器中...");
((LifeCycle) this.container).stop();
}
this.session.close();
return true;
} catch (Exception e) {
logger.trace("关闭连接时发生异常", e);
return false;
}
}
代码:从另一个类调用 close 方法
public void closeConnection() {
this.wc.close();
System.exit(1);
}
非常感谢您的帮助 :-)
英文:
I have built a client server application using javax websockets.Though JSR 356 doesn't have methods to stop websocket container, i managed to stop the container after casting to jetty Lifecyle.Once stopping the container i have wrote
> system.exit(1);
But the return is code always zero from the client program.
code:
@ClientEndpoint
public boolean close()
{
try
{
if(this.container != null && this.container instanceof LifeCycle) {
logger.trace("stoping container...");
((LifeCycle) this.container).stop();
}
this.session.close();
return true;
}
catch (Exception e)
{
logger.trace("Exception occured while closing the connection",e);
return false;
}
}
code : Invoking close method from another class
public closeConnection(){
this.wc.close();
System.exit(1);
}
Any help is appreciated
答案1
得分: 1
// 以下是翻译部分:
您是否试图从容器或容器的ThreadPool / Executor所属的线程中调用`closeConnection`或`close`?
此外,一旦停止容器,所有会话也将停止。
将`@ClientEndpoint`中的`close()`方法更改为...
``` java
public void close()
{
try
{
this.session.close();
}
catch (Exception e)
{
logger.trace("关闭连接时发生异常", e);
}
}
并将closeConnection()
方法简化为...
public closeConnection()
{
LifeCycle.stop(this.wc.getContainer());
System.exit(1);
}
您可以在以下位置找到此工作示例:
https://github.com/joakime/javaxwebsocket-client-returncode
其中包含以下代码...
App.java
package org.eclipse.jetty.demo;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.WebSocketContainer;
import org.eclipse.jetty.util.component.LifeCycle;
public class App
{
private static final App MAIN_INSTANCE = new App();
private WebSocketContainer client;
public static void main(String[] args) throws IOException, DeploymentException, URISyntaxException
{
App.MAIN_INSTANCE.connect();
}
public static void stop(int returnCode)
{
// 从不属于容器的线程触发停止。
new Thread(() ->
{
LifeCycle.stop(App.MAIN_INSTANCE.client);
System.exit(returnCode);
}).start();
}
private WebSocketContainer getClientContainer()
{
if (client == null)
client = ContainerProvider.getWebSocketContainer();
return client;
}
public void connect() throws IOException, DeploymentException, URISyntaxException
{
URI echoUri = URI.create("wss://echo.websocket.org");
ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create()
.configurator(new OriginServerConfigurator(echoUri))
.build();
EchoEndpoint echoEndpoint = new EchoEndpoint();
getClientContainer().connectToServer(echoEndpoint, clientEndpointConfig, echoUri);
System.out.printf("已连接到:%s%n", echoUri);
}
}
EchoEndpoint.java
package org.eclipse.jetty.demo;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
/**
* 基本的回声客户端终端
*/
public class EchoEndpoint extends Endpoint implements MessageHandler.Whole<String>
{
private Session session;
@Override
public void onClose(Session session, CloseReason closeReason)
{
System.out.printf("连接已关闭:Session.id=%s - %s%n", session.getId(), closeReason);
this.session = null;
}
@Override
public void onOpen(Session session, EndpointConfig config)
{
System.out.printf("已打开:Session.id=%s%n", session.getId());
this.session = session;
this.session.addMessageHandler(this);
try
{
session.getBasicRemote().sendText("你好");
session.getBasicRemote().sendText("近况如何?");
session.getBasicRemote().sendText("感谢交谈。");
}
catch (Throwable t)
{
t.printStackTrace();
}
}
@Override
public void onMessage(String msg)
{
System.out.printf("收到消息:\"%s\"%n", msg);
if (msg.contains("感谢"))
{
App.stop(1);
}
}
@Override
public void onError(Session session, Throwable cause)
{
cause.printStackTrace();
}
}
英文:
Are you attempting to call closeConnection
or close
from a thread that belongs to the container or the container's ThreadPool / Executor?
Also, once the container is stopped, all of the sessions will be stopped too.
Change @ClientEndpoint
close()
to be ...
public void close()
{
try
{
this.session.close();
}
catch (Exception e)
{
logger.trace("Exception occured while closing the connection",e);
}
}
And make closeConnection()
simply ...
public closeConnection()
{
LifeCycle.stop(this.wc.getContainer());
System.exit(1);
}
A working example of this can be found at
https://github.com/joakime/javaxwebsocket-client-returncode
Which has the code ...
App.java
package org.eclipse.jetty.demo;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.WebSocketContainer;
import org.eclipse.jetty.util.component.LifeCycle;
public class App
{
private static final App MAIN_INSTANCE = new App();
private WebSocketContainer client;
public static void main(String[] args) throws IOException, DeploymentException, URISyntaxException
{
App.MAIN_INSTANCE.connect();
}
public static void stop(int returnCode)
{
// Trigger stop from thread that does not belong to Container.
new Thread(() ->
{
LifeCycle.stop(App.MAIN_INSTANCE.client);
System.exit(returnCode);
}).start();
}
private WebSocketContainer getClientContainer()
{
if (client == null)
client = ContainerProvider.getWebSocketContainer();
return client;
}
public void connect() throws IOException, DeploymentException, URISyntaxException
{
URI echoUri = URI.create("wss://echo.websocket.org");
ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create()
.configurator(new OriginServerConfigurator(echoUri))
.build();
EchoEndpoint echoEndpoint = new EchoEndpoint();
getClientContainer().connectToServer(echoEndpoint, clientEndpointConfig, echoUri);
System.out.printf("Connected to : %s%n", echoUri);
}
}
EchoEndpoint.java
package org.eclipse.jetty.demo;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
/**
* Basic Echo Client Endpoint
*/
public class EchoEndpoint extends Endpoint implements MessageHandler.Whole<String>
{
private Session session;
@Override
public void onClose(Session session, CloseReason closeReason)
{
System.out.printf("Connection closed: Session.id=%s - %s%n", session.getId(), closeReason);
this.session = null;
}
@Override
public void onOpen(Session session, EndpointConfig config)
{
System.out.printf("Got open: Session.id=%s%n", session.getId());
this.session = session;
this.session.addMessageHandler(this);
try
{
session.getBasicRemote().sendText("Hello");
session.getBasicRemote().sendText("How are things?");
session.getBasicRemote().sendText("Thanks for the conversation.");
}
catch (Throwable t)
{
t.printStackTrace();
}
}
@Override
public void onMessage(String msg)
{
System.out.printf("Got msg: \"%s\"%n", msg);
if (msg.contains("Thanks"))
{
App.stop(1);
}
}
@Override
public void onError(Session session, Throwable cause)
{
cause.printStackTrace();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论