【问题标题】:How server can send message to client in Java服务器如何在 Java 中向客户端发送消息
【发布时间】:2015-08-08 05:37:19
【问题描述】:

发送请求时服务器返回响应。这是正常的请求-响应机制,但问题是——有时服务器需要向客户端发送一些通知。

我使用 Keep-Alive 请求实现了这一点,即服务器将要发送的消息排队,并在 ALIVE 请求到来时作为响应发送。但这会在服务器上造成瓶颈,服务器无法检测到连接是否关闭。

我相信有办法解决这个问题。我尝试过,但由于.readObject 上的ObjectOutputStream 无法同时工作而失败了。

客户端打开与服务器的连接并创建以下流进行通信。

ObjectOutputStream obos;
ObjectInputStream obis;
public Response send(Request req){
    Response resp=null;
    try {
        obos.writeObject(req); //request from Client
        resp=( Response )obis.readObject(); //Reply from server
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
    return resp;
}

public void run(){
    asyncReceive();
}

void asyncReceive(){    //notifications from server
    try {
        Message m=(Message)obis.readObject();
    } catch (ClassNotFoundException | IOException e) {
        e.printStackTrace();
    }
}

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    考虑让您的客户端也监听套接字。

    当您的客户端向服务器发送第一个请求时,它会在请求中包含它正在侦听的端口和 IP 地址。然后,服务器在该地址和端口上与客户端建立连接。然后服务器可以向客户端发送请求。

    【讨论】:

    • 如果客户端位于防火墙后面,则无法进行反向连接。发送少量消息似乎很乏味。
    • 我同意,替代方案是某种形式的长轮询。
    • 轮询方式?像客户端的定期活动请求?
    • 是的,轮询是指客户端定期询问服务器是否有消息。
    【解决方案2】:

    您也许可以使用两个不同的线程来处理接收和发送。

    发送线程可以使用线程安全的消息队列来发送,因此只要队列为空,它就会阻塞。您可以在定时器任务线程中定期将消息添加到队列中以获取通知,或作为对客户端请求的响应。

    我认为如果套接字同时关闭,readObject() 应该抛出。

    【讨论】:

    • 我相信这会起作用..但似乎是非标准的方式。你能推荐一些设计模式来看看吗?对于这样的问题。
    【解决方案3】:

    您需要一个带有消息代理的消息系统,例如RabbitMQ 或ActiveMQ,客户端需要注册到由服务器创建的主题。当服务器推送消息时,代理的工作就是通知客户端

    【讨论】:

      猜你喜欢
      • 2015-01-05
      • 2016-07-13
      • 1970-01-01
      • 2013-06-24
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多