Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HAPI-如何正确停止SimpleServer并防止进一步连接_Java_Server_Connection_Hapi - Fatal编程技术网

Java HAPI-如何正确停止SimpleServer并防止进一步连接

Java HAPI-如何正确停止SimpleServer并防止进一步连接,java,server,connection,hapi,Java,Server,Connection,Hapi,我正在构建一个应用程序,其中包含几个由CommunicationProcess类管理的服务器和客户端HL7连接。应用程序的部分功能是在添加新连接时重新启动该进程。客户端连接不会造成问题,因为一旦客户端停止,服务器端就无法重新连接。然而,对于服务器连接,我似乎立即从(相当激烈的)客户端重新连接。这是我必须停止服务器连接的代码: public void disconnect() { usageServer.getRemoteConnections().forEach((connection

我正在构建一个应用程序,其中包含几个由CommunicationProcess类管理的服务器和客户端HL7连接。应用程序的部分功能是在添加新连接时重新启动该进程。客户端连接不会造成问题,因为一旦客户端停止,服务器端就无法重新连接。然而,对于服务器连接,我似乎立即从(相当激烈的)客户端重新连接。这是我必须停止服务器连接的代码:

public void disconnect() 
{
    usageServer.getRemoteConnections().forEach((connection) -> connection.close());
    usageServer.stopAndWait();
    usageServer.getRemoteConnections().forEach((connection) -> connection.close());   
}

public void stop()
{
    running.set(false);

    disconnect();
}
这是我对connectionReceived的实现:

@Override
public void connectionReceived(Connection theC) 
{
    if (running.get())
    {
        setStatus(ConnectionStatus.CONNECTED);
    }
    else
    {
        theC.close();
    }
}
如您所见,我们的想法是在从CommunicationProcess类接收停止信号(拒绝任何新连接)时将全局AtomicBoolean设置为false,并停止服务器。无论如何,这仍然允许客户端在此过程中保持连接。客户端是一个我不允许命名的应用程序,但它已经存在了十多年,我知道事实上它不会成为问题,因为多年来我一直支持它作为我日常工作的一部分,它的行为根本不是这样的

你知道为什么我的代码没有真正终止连接吗?我觉得我已经研究了很多这个API,我没有找到一种方法来注销连接侦听器,这可能会解决这个问题。此外,我无法扩展这些服务器类,因为所有的东西都被极度地封装和私有化了


谢谢

我正在查看HAPI库的代码

您所描述的行为原因可能如下

当服务器启动时,它们会创建一个名为
acceptorhread
的组件。顾名思义,该线程的职责是初始化将用于接收传入客户端连接的
ServerSocket
,并接受它们

与API提出的每个
服务
抽象一样,该线程在如下循环中运行:

/**
*运行线程。
* 
*@see java.lang.Runnable#run()
*/
公开最终作废运行(){
试一试{
启动后();
debug(“线程{}进入主循环”,名称);
while(isRunning()){
句柄();
startupLatch.countDown();
}
调试(“线程{}离开主循环”,名称);
}捕获(运行时异常t){
如果(t.getCause()!=null){
serviceExitedWithException=t.getCause();
}否则{
serviceExitedWithException=t;
}
log.warn(“由于异常退出主循环的线程:,t”);
}捕获(可丢弃的t){
serviceExitedWithException=t;
log.warn(“由于异常退出主循环的线程:,t”);
}最后{
startupLatch.countDown();
后终止();
}
}
当您在服务器中调用方法
stopAndWait
时,它也会尝试停止此线程

stop进程基本上更改了控制组件``ìsRunning()``是否运行的
布尔
标志

如您所见,尽管它将标志设置为
false
,但循环中方法
句柄的调用仍然必须结束

这是
acceptorhread
handle
方法的实现:

@覆盖
受保护的无效句柄(){
试一试{
套接字s=ss.accept();
socketFactory。配置新的AcceptedSocket;
如果(!queue.offer(新的AcceptedSocket))){
错误(“拒绝排队服务器端套接字{}”,s);
s、 close();
}否则
debug(“排队的服务器端套接字{}”,s);
}catch(SocketTimeoutException e){/*好-刚刚超时*/
log.trace(“等待时未建立连接”);
}捕获(IOE异常){
log.error(“接受连接时出错”,e);
}
}
如您所见,该方法调用
ServerSocket.accept
,从而允许新的传入连接

为了断开此服务器端套接字的连接,我们可以从另一个线程调用
close

事实上,此过程是通过
acceptorread
后终止
方法实现的:

@覆盖
受保护的无效后终止(){
试一试{
如果(ss!=null&&!ss.isClosed())
ss.close();
}捕获(IOE异常){
log.warn(“停止线程时出错”,e);
}
}
不幸的是,你是对的,API非常接近没有明确的方法可以做到这一点

一种可能的解决方案是实现您自己的
HL7Service
,命名为
MySimpleServer
,使用
SimpleServer
的代码作为基线,只需在终止后更改方法
的实现即可:

/**
*封闭式插座
*/
@凌驾
受保护的无效后终止(){
超级后终止();
//终止服务器端套接字
接受者。后终止();
//终止接受线程本身
acceptor.close();
}
请注意:我们不调用
acceptor.stop()
而是调用
acceptor.aftermination()
直接关闭底层服务器端套接字

为了避免
acceptorhread
中的
handle
方法引发的错误,我们还可以从原始类中实现一个新类,或者仅尝试覆盖
handle
方法,以便在服务器端套接字关闭时考虑:

@覆盖
受保护的无效句柄(){
试一试{
if(ss.isClosed()){
debug(“服务器端套接字已关闭。不允许新连接”);
返回;
}
套接字s=ss.accept();
socketFactory。配置新的AcceptedSocket;
如果(!queue.offer(新的AcceptedSocket))){
错误(“拒绝排队服务器端套接字{}”,s);
s、 close();
}否则
debug(“排队的服务器端套接字{}”,s);
}catch(SocketTimeoutException e){/*好-刚刚超时*/
log.trace(“无连接