rupinderjeet
rupinderjeet

Reputation: 2838

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

I have one index.jsp file, one connect.java servlet and one Server.java file which creates a chat server.

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>

connect 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");

It prints Server is online at XXXX

But, after this, i think printWriter becomes unusable, maybe entire link of index.jsp page to threaded Server.java object gets broken. Because, form action="connect" is completely performed and server is started and it doesn't wait for clients to get connected.

now, if i add following to Server.java

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

and if, now, client connects to Server, printWriter statement doesn't print anything (maybe because the actual web-page needs to be refreshed, but why? how can i make it dynamic if this is the problem? ).

I can verify that client gets connected successfully because if i uncomment the JOptionPane statement, it shows when a client gets connected. So, no issues on client-side.

How can i make the printWriter statement work? Somehow, keep the connection between JSP and Server.java alive. Make the Servlet/JSP continuously listen to Server.java

index.jsp view index.jsp

connect.java servlet view connect.java

  1. I didn't have a perfect title for this question.
  2. If this is impossible, kindly write an alternative.

Upvotes: 0

Views: 345

Answers (1)

BalusC
BalusC

Reputation: 1109162

Don't do that. Passing around HTTP request/response related state to a different thread outside the HTTP thread is recipe for disaster. Once the servlet doXxx() method returns, then the request/response objects and all of its related state are garbaged (simply because they're finished doing their HTTP based job) and become unusable (so any attempt to use them anyway would only result in unexpected behavior or exceptions like IllegalStateException). Never do that.

As to your concrete functional requirement of opening a persistent two-way client-server socket connection, you seem to be confusing desktop applications with web applications while searching for solutions. The code which you've there would only work for desktop applications. For web applications, you need web sockets instead. Use JavaScript's window.WebSocket API in client side (tutorial here) and Java EE's javax.websocket API (JSR356) in server side (tutorial here).

Do note that this API is very low level, it's nearly as low level as HTTP. For instance, in the Servlet API you have "session" scope ready for direct use and you can easily identify users and all, but in WebSocket API not. You have to (re)invent and code all the scopes/layers yourself. If you can, rather go for an existing library/framework. For example, Java EE's own MVC framework JSF has several libraries (plugins) available for the job, such as OmniFaces <o:socket> tag which is demonstrated here (and developed by yours truly).

See also:

Upvotes: 1

Related Questions