Note that there are some explanatory texts on larger screens.

plurals
  1. PONetty ClientBootstrap RECONNECT to another server
    text
    copied!<p>I have a question about ClientBootStrap. Here is the scenario;</p> <ol> <li>Client_X wants to join Server_A. </li> <li>But the Server_A somehow wants the Client_x to join in Server_B.</li> <li>So Server_A sends Server_B's info to Client_X for RECONNECTION</li> <li>As soon as the Client_X gets the RECONNECTION message, he tries disconnecting from Server_A and tries to connecting to Server_B. But it fails. Because as soon as Client disconnects from Server_A, he cannot use the disconnected channel anymore. </li> </ol> <p>This looks simple. But here is my implementation</p> <pre><code> @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)throws Exception { if(e.getMessage() instanceof SomePacket){ .... }else if(e.getMessage() instanceof Reconnect){ //Server_A has sent a RECONNECT Message.(Redirection) Reconnect theReconnectPacket = (Reconnect)e.getMessage(); String hostname = theReconnectPacket.getHostname(); int port = theReconnectPacket.getPort(); this.reconnectHost = hostname; this.reconnectPort = port; this.currentState = 1; ctx.getChannel().disconnect(); //DISCONNECT FROM SERVER_A } } @Override public void channelDisconnected(ChannelHandlerContext ctx,ChannelStateEvent e) throws Exception { if(this.currentState == 1){ Channel disconnectedChannel = ctx.getChannel(); if (!disconnectedChannel.isConnected()){ SocketAddress destinationAddress = new InetSocketAddress(this.reconnectHost, this.reconnectPort); //TRYING TO RECONNECT SERVER_B disconnectedChannel.connect(destinationAddress); //**Error Line:java.nio.channels.ClosedChannelException** } } super.channelDisconnected(ctx, e); } </code></pre> <p>As you can see in the <strong>Error Line</strong>, I got this exception:java.nio.channels.ClosedChannelException. Couldn't we use the same channel after it is disconnected?. Once it is disconnected, is it done?. How could we recreate a connection in the SimpleChannelHandler ?</p> <p>Thanks for further comments :)</p> <p>&lt;&lt;&lt;&lt;&lt; NEW APPROACH >>>>>></p> <p>Ok. So in the SimpleChannledHandler , I use ClientBootStrap to connect a differentPort.</p> <pre><code> @Override public void channelDisconnected(ChannelHandlerContext ctx,ChannelStateEvent e) throws Exception { Channel disconnectedChannel = ctx.getChannel(); final ClientDataObject oldObject = ClientDataState.clientObject.get(disconnectedChannel); if(oldObject.getClientState() == 1){ if (!disconnectedChannel.isConnected()){ SocketAddress destinationAddress = new InetSocketAddress(this.reconnectHost, this.reconnectPort); ChannelFuture connectFuture = bootstrap.connect(destinationAddress); connectFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture channelFuture) throws Exception { Channel newChannel = channelFuture.getChannel(); ClientDataObject newObject = ClientDataState.clientObject.get(newChannel); newObject.setClientID(oldObject.getClientID()); newObject.setClientState(oldObject.getClientState()); newObject.setRoomId(oldObject.getRoomId()); newObject.setClientState(1); ClientDataState.clientObject.set(newChannel, newObject); Channels.write(newChannel, new Login(newObject.getClientID())); }}); }else{ //Channled connected } } super.channelDisconnected(ctx, e); } </code></pre> <p>But I need to know some information of Client_X. As soon as the Client_x is disconnected the pipeline create another SimpleChannelHandler. So all my information is gone. I try to use ChannelLocal to keep state of the client. But it is also useless since it is related with channel object. When I connect to newChannel I cannot use old SimpleChannelHandlers's data again. (like clientID,roomID etc.)</p> <p>My point is how to store information without being effected by channel(session), I want to access the data from any channel handler. </p> <p>The way to handle this question should we implement ChannelPipelineFactory like this?</p> <pre><code> public class GameClientPipelineFactory implements ChannelPipelineFactory{ private static final ClientStaticHandler SHARED = new ClientStaticHandler(); private Someobject o; public GameClientPipelineFactory(Someobject refTOSomeObject) { super(); this.o = refToSomeObject; } @Override public ChannelPipeline getPipeline() throws Exception { // TODO Auto-generated method stub ChannelPipeline pipeline = Channels.pipeline(); //pipeline.addLast("delimiter", new DelimiterBasedFrameDecoder(256, Delimiters.lineDelimiter())); pipeline.addLast("decoder", new GameClientDecoder()); pipeline.addLast("encoder", new GameClientEncoder()); pipeline.addLast("shared", SHARED); //I added this line pipeline.addLast("logicHandler", new GameClientLogicHandler(this.o)); return pipeline; } </code></pre> <p>But then how am I gonna use this 'shared' handler? Each time when I need a global object, should I ask to pipeline to get this handler and get any object from 'shared' handler? Isn't this a long way?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload