1313import org .menacheri .jetserver .app .GameRoom ;
1414import org .menacheri .jetserver .app .Player ;
1515import org .menacheri .jetserver .app .PlayerSession ;
16+ import org .menacheri .jetserver .app .Session ;
1617import org .menacheri .jetserver .communication .NettyTCPMessageSender ;
1718import org .menacheri .jetserver .event .Event ;
1819import org .menacheri .jetserver .event .Events ;
1920import org .menacheri .jetserver .event .impl .DefaultEvent ;
21+ import org .menacheri .jetserver .event .impl .ReconnetEvent ;
2022import org .menacheri .jetserver .service .LookupService ;
2123import org .menacheri .jetserver .service .UniqueIDGeneratorService ;
2224import org .menacheri .jetserver .service .impl .ReconnectSessionRegistry ;
2325import org .menacheri .jetserver .util .Credentials ;
26+ import org .menacheri .jetserver .util .JetConfig ;
2427import org .menacheri .jetserver .util .SimpleCredentials ;
2528import org .slf4j .Logger ;
2629import org .slf4j .LoggerFactory ;
@@ -60,8 +63,8 @@ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
6063 String data = frame .getText ();
6164 LOG .trace ("From websocket: " + data );
6265 Event event = gson .fromJson (data , DefaultEvent .class );
63-
64- if (Events .LOG_IN == event . getType () )
66+ int type = event . getType ();
67+ if (Events .LOG_IN == type )
6568 {
6669 LOG .trace ("Login attempt from {}" , channel .getRemoteAddress ());
6770 List <String > credList = null ;
@@ -70,6 +73,12 @@ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
7073 handleLogin (player , channel );
7174 handleGameRoomJoin (player , channel , credList .get (2 ));
7275 }
76+ else if (type == Events .RECONNECT )
77+ {
78+ LOG .debug ("Reconnect attempt from {}" , channel .getRemoteAddress ());
79+ PlayerSession playerSession = lookupSession ((String )event .getSource ());
80+ handleReconnect (playerSession , channel );
81+ }
7382 else
7483 {
7584 LOG .error (
@@ -86,6 +95,60 @@ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
8695 }
8796 }
8897
98+ public PlayerSession lookupSession (final String reconnectKey )
99+ {
100+ PlayerSession playerSession = (PlayerSession )reconnectRegistry .getSession (reconnectKey );
101+ if (null != playerSession )
102+ {
103+ synchronized (playerSession ){
104+ // if its an already active session then do not allow a
105+ // reconnect. So the only state in which a client is allowed to
106+ // reconnect is if it is "NOT_CONNECTED"
107+ if (playerSession .getStatus () == Session .Status .NOT_CONNECTED )
108+ {
109+ playerSession .setStatus (Session .Status .CONNECTING );
110+ }
111+ else
112+ {
113+ playerSession = null ;
114+ }
115+ }
116+ }
117+ return playerSession ;
118+ }
119+
120+ protected void handleReconnect (PlayerSession playerSession , Channel channel )
121+ {
122+ if (null != playerSession )
123+ {
124+ channel .write (eventToFrame (Events .LOG_IN_SUCCESS , null ));
125+ GameRoom gameRoom = playerSession .getGameRoom ();
126+ gameRoom .disconnectSession (playerSession );
127+ if (null != playerSession .getTcpSender ())
128+ playerSession .getTcpSender ().close ();
129+
130+ handleReJoin (playerSession , gameRoom , channel );
131+ }
132+ else
133+ {
134+ // Write future and close channel
135+ closeChannelWithLoginFailure (channel );
136+ }
137+ }
138+
139+ protected void handleReJoin (PlayerSession playerSession , GameRoom gameRoom , Channel channel )
140+ {
141+ // Set the tcp channel on the session.
142+ NettyTCPMessageSender sender = new NettyTCPMessageSender (channel );
143+ playerSession .setTcpSender (sender );
144+ // Connect the pipeline to the game room.
145+ gameRoom .connectSession (playerSession );
146+ channel .write (Events .GAME_ROOM_JOIN_SUCCESS , null );//assumes that the protocol applied will take care of event objects.
147+ playerSession .setWriteable (true );// TODO remove if unnecessary. It should be done in start event
148+ // Send the re-connect event so that it will in turn send the START event.
149+ playerSession .onEvent (new ReconnetEvent (sender ));
150+ }
151+
89152 public Player lookupPlayer (String username , String password )
90153 {
91154 Credentials credentials = new SimpleCredentials (username , password );
@@ -124,10 +187,14 @@ public void handleGameRoomJoin(Player player, Channel channel, String refKey)
124187 {
125188 PlayerSession playerSession = gameRoom .createPlayerSession (player );
126189 gameRoom .onLogin (playerSession );
190+ String reconnectKey = (String )idGeneratorService
191+ .generateFor (playerSession .getClass ());
192+ playerSession .setAttribute (JetConfig .RECONNECT_KEY , reconnectKey );
193+ playerSession .setAttribute (JetConfig .RECONNECT_REGISTRY , reconnectRegistry );
127194 LOG .trace ("Sending GAME_ROOM_JOIN_SUCCESS to channel {}" ,
128195 channel .getId ());
129196 ChannelFuture future = channel .write (eventToFrame (
130- Events .GAME_ROOM_JOIN_SUCCESS , null ));
197+ Events .GAME_ROOM_JOIN_SUCCESS , reconnectKey ));
131198 connectToGameRoom (gameRoom , playerSession , future );
132199 }
133200 else
0 commit comments