2

In my Java Sockets program, I have implemented a client-server Observer pattern. That is, the server subject publishes its server events to client observers that have subscribed to the server. That's the theory.

In practice, I am unable to send the client observer through the socket to subscribe to the server. The error that comes up is: "java.io.NotSerializableException: java.net.Socket." I think this means Java is complaining that the client observer contains a Socket which, as we all know, is not Serializable.

However, the Socket is the means of communication between the client and the server!

How can I implement a client-server Observer pattern when the client appears to contain a non-Serializable roadblock?

Here is a code overview to give you an understanding of what is happening:

Server

public class Server implements ServerSocketPublisher {

    // traditional Observer publisher methods implemented here, such as register, 
    // deregister, notifySubscribers

    // ServerSocket implemented here. Waiting on accept()

}

Client

public class Client implements ClientSocketSubscriber, Serializable {

    // traditional Observer subscriber methods implemented here, i.e. updateClient

    Socket connectingSocket = null; //I SUSPECT THIS VARIABLE IS THE PROBLEM

    try {
         connectingSocket = new Socket();
         // set SocketAddress and timeout
         connectingSocket.connect(sockAddr, timeout)
         if (connectingSocket.isConnected()) {
             ObjectOutputStream oos = new ObjectOutputStream     
                  (connectingSocket.getOutputStream());
             oos.writeObject(this); // THIS LINE THROWS THE ERROR in STACKTRACES
             oos.flush();
             oos.close();
         }
    } catch (/*various exceptions*/) {
    }
    // close connectingSocket
}
Arvanem
  • 1,043
  • 12
  • 22

2 Answers2

3

You have couple of ways to get this fixed:

  1. Mark your socket as transient

    transient Socket connectingSocket = null;

  2. Instead of implementing Serializable implement Externalizable and then in your implementation of read and write object ignore the Socket.

Along with this you should also read

About transient:

  1. Post on SO

About Externalizable :

  1. Javabeat
Community
  • 1
  • 1
mprabhat
  • 20,107
  • 7
  • 46
  • 63
1

you cannot write the Client to the output stream socket since it contains a Socket. If you serialize the Client, you serialize all non-transient vars in it, and thats when you get the exception.

However, the server already has the socket on its side, so you don't need to send it and the client across. If all clients are observers once the connection has occurred you can pretty much at that point start waiting for data from the socket on the client side. The server will need to keep a list of sockets its ready to broadcast to, and when it gets an event to send, loop over all sockets and send the register, deregister, notifySubscriber messages

Alternatively if you wish to treat the client as an object on the server side and call methods on it (which it looks like you might be trying to do), maybe you need to look into RMI - where the server holds stubs of the client and invoking the stub sends messages to the client.

Bruce Lowe
  • 6,063
  • 1
  • 36
  • 47
  • +1 for your taking the time to set forth some interesting thoughts. I will give some thought to trying to implement your ideas. – Arvanem Apr 28 '12 at 14:29