Closed jan-burianek closed 8 years ago
Hi @jan-burianek!
Could you please tell us the steps to reproduce this issue?
Yes, also please print out all the protocols received on the server. Print statement in Request.doParse()
The issue may be reproduced like this:
version = DataReader.readString(dataInput).trim();
user_id = DataReader.readString(dataInput).trim();
password = DataReader.readString(dataInput).trim();
player_id = DataReader.readInt(dataInput);
room_id = DataReader.readInt(dataInput);
// Nothing to parse;
Error statement:
Request [115] Error:
null
---
java.lang.NullPointerException
at networking.request.RequestRRGetMap.doBusiness(RequestRRGetMap.java:32)
at core.GameClient.run(GameClient.java:122)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
@jkrubin @laisture Could you guys take a look at this as well? The more eyes the better. Thanks!
Sorry I haven't had time to read any code this weekend. I'll try to figure it out by Monday night
Sent from my iPhone
On Apr 9, 2016, at 2:39 PM, Nicu Listana notifications@github.com wrote:
@jkrubin @laisture Could you guys take a look at this as well? The more eyes the better. Thanks!
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub
@rujoota @anuagg Hi server team members, can you look at this issue? Do you have any experience like this? Any clue?
@jan-burianek Are you sure, you running the latest server and client code on your local machine? These test results are when you tried running unity code connected to server running at your local machine or remote server ( 520.something / thecity server )? See when I tried the same by running server code locally and then connecting to a client, it works fine for me. So, in my opinion issue might be that you are not getting connected with the running rhino server. Reasons might be:
And having two threads for a single client might be a part of running rhino's code design. I think this has nothing to do with the errors you are getting.
Hi @jan-burianek, I am also facing similar issue. I keep on getting null exception on various objects on my server. Not sure if these are because of threading issue. I tried running jar separately on different port. My config files are properly set. Tried to debug this issue, but it seems not replicating at exact same line.
@worldofbalance/server Let's have a debugging session together at class.
Strangely enough, when I created our server in different netbeans solution and ran in parallel with wob-server, this doesn't happen.
@anuagg I am 120% sure that I'm running a current server instance on my local machine and also that my client does communicate with it. If you are using some POSIX friendly OS, netstat -luntp
may say a few things about your client / server interaction. I am also sure that login credentials have no impact on this issue since they are not validated by the server at all. According to me, this issue is clearly "thread based" and a solution may come to the surface only by figuring out why two threads are created instead of one. Unfortunately, it might be rooted at a very low level...
@rujoota Wow... maybe it's platform specific or it's even some another thing, I'm running the server on JDK 1.8, OS X, but I think we should not rely on the correct "random" running environment and figure out what causes this issue... I'll try some other JVM debugging tools
@jan-burianek I am using same environment. I have a feeling that because we are using many shared classes from wob-server, it might be creating race conditions.
@jan-burianek Jan, I want to know if this happened at the old last semester code or the problem started once we restructured the server code. Then finding solution would be easier. Can you run the same tracking using the code from last year (that Jens posted) and see if it creates two thread at the same point?
Good idea. If you check out master you would be able to run last year's code.
OK, I can make it
I have something.
At first, I let the each server thread print its call stack right after the thread came to life, the result is:
RunnerItems list successfully loaded.
Server has started on port: 20039
Waiting for clients...
127.0.0.1 is connecting...
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 Thread has been just created
Stack Trace:
Timer-0:
java.lang.Object.wait(Native Method)
java.util.TimerThread.mainLoop(Timer.java:552)
java.util.TimerThread.run(Timer.java:505)
main:
java.net.PlainSocketImpl.socketAccept(Native Method)
java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
java.net.ServerSocket.implAccept(ServerSocket.java:545)
java.net.ServerSocket.accept(ServerSocket.java:513)
core.GameServer.run(GameServer.java:226)
core.GameServer.main(GameServer.java:367)
Abandoned connection cleanup thread:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158)
com.mysql.jdbc.NonRegisteringDriver$1.run(NonRegisteringDriver.java:93)
Finalizer:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158)
java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
Reference Handler:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:502)
java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
pool-1-thread-1:
java.lang.Thread.dumpThreads(Native Method)
java.lang.Thread.getAllStackTraces(Thread.java:1603)
core.GameClient.run(GameClient.java:90)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Signal Dispatcher:
127.0.0.1 is connecting...
Thread ID: 15 Session ID: 48097013-4b4a-4c73-afcf-cbec364e6f37 Thread has been just created
Stack Trace:
pool-1-thread-2:
java.lang.Thread.dumpThreads(Native Method)
java.lang.Thread.getAllStackTraces(Thread.java:1603)
core.GameClient.run(GameClient.java:90)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Timer-0:
java.lang.Object.wait(Native Method)
java.util.TimerThread.mainLoop(Timer.java:552)
java.util.TimerThread.run(Timer.java:505)
main:
java.net.PlainSocketImpl.socketAccept(Native Method)
java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
java.net.ServerSocket.implAccept(ServerSocket.java:545)
java.net.ServerSocket.accept(ServerSocket.java:513)
core.GameServer.run(GameServer.java:226)
core.GameServer.main(GameServer.java:367)
Abandoned connection cleanup thread:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158)
com.mysql.jdbc.NonRegisteringDriver$1.run(NonRegisteringDriver.java:93)
Finalizer:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158)
java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
Reference Handler:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:502)
java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
pool-1-thread-1:
java.lang.System.currentTimeMillis(Native Method)
core.GameClient.run(GameClient.java:150)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Signal Dispatcher:
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Thread ID: 14 Session ID: ae7e9807-c0f6-4f93-8d9b-006b7557b400 User ID: player does not exists
Disconnected from the target VM, address: '127.0.0.1:64946', transport: 'socket'
Process finished with exit code 130
So both threads appear to be created regularly at the same place. So I tried to track the traffic between client and server and this is a sample of the result:
1 0.000000 127.0.0.1 127.0.0.1 TCP 56 58983 → 20039
[FIN, ACK] Seq=1 Ack=1 Win=12759 Len=0 TSval=378781082 TSecr=378564753
Frame 1: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 58983 (58983), Dst Port: 20039 (20039), Seq: 1, Ack: 1,
Len: 0
2 0.000073 127.0.0.1 127.0.0.1 TCP 56
[ACK] Seq=1 Ack=2 Win=12759 Len=0 TSval=378781082 TSecr=378781082
Frame 2: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 58983 (58983), Seq: 1, Ack: 2,
Len: 0
3 1.374882 127.0.0.1 127.0.0.1 TCP 68 57512 → 20039
[SYN] Seq=0 Win=65535 Len=0 MSS=16344 WS=32 TSval=378782448 TSecr=0 SACK_PERM=1
Frame 3: 68 bytes on wire (544 bits), 68 bytes captured (544 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57512 (57512), Dst Port: 20039 (20039), Seq: 0, Len: 0
4 1.374980 127.0.0.1 127.0.0.1 TCP 68 20039 → 57512
[SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=16344 WS=32 TSval=378782448 TSecr=378782448
SACK_PERM=1
Frame 4: 68 bytes on wire (544 bits), 68 bytes captured (544 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57512 (57512), Seq: 0, Ack: 1,
Len: 0
5 1.374992 127.0.0.1 127.0.0.1 TCP 56
[ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=378782448 TSecr=378782448
Frame 5: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57512 (57512), Dst Port: 20039 (20039), Seq: 1, Ack: 1,
Len: 0
6 1.375004 127.0.0.1 127.0.0.1 TCP 56 [TCP Window
Update] 20039 → 57512 [ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=378782448 TSecr=378782448
Frame 6: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57512 (57512), Seq: 1, Ack: 1,
Len: 0
7 1.459383 127.0.0.1 127.0.0.1 TCP 68 57514 → 20039
[SYN] Seq=0 Win=65535 Len=0 MSS=16344 WS=32 TSval=378782533 TSecr=0 SACK_PERM=1
Frame 7: 68 bytes on wire (544 bits), 68 bytes captured (544 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57514 (57514), Dst Port: 20039 (20039), Seq: 0, Len: 0
8 1.459451 127.0.0.1 127.0.0.1 TCP 68 20039 → 57514
[SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=16344 WS=32 TSval=378782533 TSecr=378782533
SACK_PERM=1
Frame 8: 68 bytes on wire (544 bits), 68 bytes captured (544 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57514 (57514), Seq: 0, Ack: 1,
Len: 0
9 1.459468 127.0.0.1 127.0.0.1 TCP 56
[ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=378782533 TSecr=378782533
Frame 9: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57514 (57514), Dst Port: 20039 (20039), Seq: 1, Ack: 1,
Len: 0
10 1.459483 127.0.0.1 127.0.0.1 TCP 56 [TCP Window
Update] 20039 → 57514 [ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=378782533 TSecr=378782533
Frame 10: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/LoopbackInternet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57514 (57514), Seq: 1, Ack: 1,
Len: 0
11 2.923715 127.0.0.1 127.0.0.1 TCP 60
[PSH, ACK] Seq=1 Ack=1 Win=408288 Len=4 TSval=378783974 TSecr=378782448
Frame 11: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57512 (57512), Dst Port: 20039 (20039), Seq: 1, Ack: 1,
Len: 4
Data (4 bytes)
0000 02 00 66 00 ..f.
12 2.923743 127.0.0.1 127.0.0.1 TCP 56
[ACK] Seq=1 Ack=5 Win=408288 Len=0 TSval=378783974 TSecr=378783974
Frame 12: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57512 (57512), Seq: 1, Ack: 5,
Len: 0
13 3.926834 127.0.0.1 127.0.0.1 TCP 60
[PSH, ACK] Seq=5 Ack=1 Win=408288 Len=4 TSval=378784972 TSecr=378783974
Frame 13: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57512 (57512), Dst Port: 20039 (20039), Seq: 5, Ack: 1,
Len: 4
Data (4 bytes)
0000 02 00 66 00 ..f.
14 3.926858 127.0.0.1 127.0.0.1 TCP 56
[ACK] Seq=1 Ack=9 Win=408288 Len=0 TSval=378784972 TSecr=378784972
Frame 14: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57512 (57512), Seq: 1, Ack: 9,
Len: 0
15 4.936892 127.0.0.1 127.0.0.1 TCP 60
[PSH, ACK] Seq=9 Ack=1 Win=408288 Len=4 TSval=378785977 TSecr=378784972
Frame 15: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57512 (57512), Dst Port: 20039 (20039), Seq: 9, Ack: 1,
Len: 4
Data (4 bytes)
0000 02 00 66 00 ..f.
16 4.936928 127.0.0.1 127.0.0.1
[ACK] Seq=1 Ack=13 Win=408288 Len=0 TSval=378785977 TSecr=378785977
Frame 16: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57512 (57512), Seq: 1, Ack:
13, Len: 0
17 5.939177 127.0.0.1 127.0.0.1 TCP 60
[PSH, ACK] Seq=13 Ack=1 Win=408288 Len=4 TSval=378786976 TSecr=378785977
Frame 17: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 57512 (57512), Dst Port: 20039 (20039), Seq: 13, Ack:
1, Len: 4
Data (4 bytes)
0000 02 00 66 00 ..f.
18 5.939199 127.0.0.1 127.0.0.1
[ACK] Seq=1 Ack=17 Win=408256 Len=0 TSval=378786976 TSecr=378786976
Frame 18: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 20039 (20039), Dst Port: 57512 (57512), Seq: 1, Ack:
17, Len: 0, etc...
What is weird about this output is that (because of timing) it looks like the client is communicating with the server trough two sockets at the same time. You can see the direction at e.g. Src Port: 20039 (20039), Dst Port: 57512
and the other way Src Port: 57512 (57512), Dst Port: 20039 (20039)
So it is quite likely that this is not a server issue but client may be sending two requests, for some reason I'm not familiar with so far.
So there comes another mysterious issue: why and where the client is doing this and why it is sending RequestLogin
and RequestRaceInit
requests over another socket than the RequestRRGetMap
request.
@jan-burianek I believe that it's because the RR server used to be a separate server before, and it's stil acting like it is, so my guess would be that when you send a new RequestLogin, it will notice that you are already logged in and will log you out and then try to log you in again. Please look at line 59 to 62 in RequestLogin at: https://github.com/worldofbalance/wob-server/blob/development/src/rr/net/request/RequestLogin.java
This is just my guess. @ilmiyoon @niculistana @jkrubin
Ultimate solution from @jan-burianek @Fito just to make it public and consistent across all the games:
The thing is that if you are retrieving ConnectionManager
from Unity like
RRConnectionManager cManager = gameObject.GetComponent<RRConnectionManager>();
it may return completely new instance every time (and that's bad). To avoid this issue, connection manager has to be created on one place as a Unity component:
gameObject.AddComponent<RRConnectionManager>();
and every time you need to use the ConnectionManager, it may be retrieved as a singleton instance:
RRConnectionManager cManager = RRConnectionManager.getInstance();
@jan-burianek Good idea to making it a singleton instance. Thank you for the solution. Please update and make a pull request.
As soon as a client is connected to a socket, 2 threads are created ID 12, 13 (my case) every request is processed by thread ID 12 but RequestRRGetMap (thread ID 13) which terminates everything because thread ID 13 is "empty".