在 Servlet 执行后使 PrintWriter 工作 - 当 serversocket 接受连接时由 socket 客户端调用

make PrintWriter work after Servlet execution - invoked by socket client when serversocket accepts connection

我有一个 index.jsp 文件、一个 connect.java servlet 和一个创建聊天服务器的 Server.java 文件。

index.jsp

<form action="connect">
    <textarea name="chat-window" ></textarea>
    <input name="port-number" placeholder="enter-port"/>
    <select name="action-type">
        <option> start </option>
        <option> stop </option>
        <option> refresh </option>
    </select>
    <button name="apply-btn" type="submit"> apply </button>
</form>

连接 servlet

// creates new thread(runnable) to run Server.java and 
// passes portNumber, printWriter object generated by response.getWriter() to Server.java

Server.java

// creates serverSocket on portNumber
try {
    serverSocket = new ServerSocket(portNumber); 
} catch (IOException e) {
    showException("Server.startRunning(): new ServerSocket() ", e);
}

printWriter.println("Server is online at " + portNumber + " \n");

它打印 Server is online at XXXX

但是,在此之后,我认为 printWriter 变得无法使用,也许整个 index.jsp 页面的 link 到线程 Server.java object 被破坏了。因为,form action="connect" 已完全执行并且服务器已启动,它不会等待 clients 连接。

现在,如果我将以下内容添加到 Server.java

while(true) {
    try {
        clientSocket = serverSocket.accept();
        printWriter.println("Client Connected.");
        // JOptionPane.showMessageDialog("Client Connected.", null);
    } catch() {
        // Exception handling mechanism
    }
}

如果现在 client 连接到 ServerprintWriter 语句不会打印任何内容(可能是因为实际的 web-page 需要刷新,但是为什么?如果这是问题所在,我怎样才能使它动态化?)。

我可以验证 client 是否成功连接,因为如果我取消注释 JOptionPane 语句,它会显示 client 何时连接。所以,client-side.

没有问题

如何使 printWriter 语句生效?以某种方式保持 JSPServer.java 之间的连接。让 Servlet/JSP 连续收听 Server.java

index.jsp 查看

connect.java servlet 视图

  1. 这个问题我没有一个完美的标题。
  2. 如果这不可能,请写一个替代方案。

不要那样做。将 HTTP request/response 相关状态传递给 HTTP 线程之外的另一个线程是灾难的根源。一旦 servlet doXxx() 方法 returns,那么 request/response 对象及其所有相关状态都被丢弃(仅仅是因为它们完成了基于 HTTP 的工作)并且变得不可用(所以任何无论如何尝试使用它们只会导致意外行为或异常,如 IllegalStateException)。 Never do that.

关于您打开持久双向客户端-服务器套接字连接的具体功能需求,您在寻找解决方案时似乎将桌面应用程序与 Web 应用程序混淆了。您拥有的代码仅适用于桌面应用程序。 对于网络应用程序,您需要网络套接字。使用 Java脚本的 window.WebSocket API in client side (tutorial here) and Java EE's javax.websocket API (JSR356) in server side (tutorial here).

请注意,此 API 级别非常低,几乎与 HTTP 一样低级别。例如,在 Servlet API 中,您可以直接使用“会话”范围,并且可以轻松识别用户和所有用户,但在 WebSocket API 中则不然。您必须自己(重新)发明和编码所有 scopes/layers。如果可以,宁愿选择现有的 library/framework。例如,Java EE 自己的 MVC 框架 JSF has several libraries (plugins) available for the job, such as OmniFaces <o:socket> tag which is demonstrated 这里(真正由您开发)。

另请参阅:

  • Real time updates from database using JSF/Java EE