aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/TCPJSONStream/TCPJsonWebSocketServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/TCPJSONStream/TCPJsonWebSocketServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/TCPJSONStream/TCPJsonWebSocketServer.cs163
1 files changed, 163 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/TCPJSONStream/TCPJsonWebSocketServer.cs b/OpenSim/Region/ClientStack/TCPJSONStream/TCPJsonWebSocketServer.cs
new file mode 100644
index 0000000..0713bf4
--- /dev/null
+++ b/OpenSim/Region/ClientStack/TCPJSONStream/TCPJsonWebSocketServer.cs
@@ -0,0 +1,163 @@
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Net.Sockets;
5using System.Reflection;
6using System.Text;
7using System.Threading;
8using Nini.Config;
9using OpenSim.Framework;
10using OpenSim.Region.Framework.Scenes;
11using log4net;
12
13namespace OpenSim.Region.ClientStack.TCPJSONStream
14{
15 public delegate void ExceptionHandler(object source, Exception exception);
16
17 public class TCPJsonWebSocketServer
18 {
19 private readonly IPAddress _address;
20 private readonly int _port;
21 private readonly ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
22 private TcpListener _listener;
23 private int _pendingAccepts;
24 private bool _shutdown;
25 private int _backlogAcceptQueueLength = 5;
26 private Scene m_scene;
27 private Location m_location;
28 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
29
30 public event EventHandler<ClientAcceptedEventArgs> Accepted = delegate { };
31
32
33 public TCPJsonWebSocketServer(IPAddress _listenIP, ref uint port, int proxyPortOffsetParm,
34 bool allow_alternate_port, IConfigSource configSource,
35 AgentCircuitManager authenticateClass)
36 {
37 _address = _listenIP;
38 _port = (int)port; //Why is a uint passed in?
39 }
40 public void Stop()
41 {
42 _shutdown = true;
43 _listener.Stop();
44 if (!_shutdownEvent.WaitOne())
45 m_log.Error("[WEBSOCKETSERVER]: Failed to shutdown listener properly.");
46 _listener = null;
47 }
48
49 public bool HandlesRegion(Location x)
50 {
51 return x == m_location;
52 }
53
54 public void AddScene(IScene scene)
55 {
56 if (m_scene != null)
57 {
58 m_log.Debug("[WEBSOCKETSERVER]: AddScene() called but I already have a scene.");
59 return;
60 }
61 if (!(scene is Scene))
62 {
63 m_log.Error("[WEBSOCKETSERVER]: AddScene() called with an unrecognized scene type " + scene.GetType());
64 return;
65 }
66
67 m_scene = (Scene)scene;
68 m_location = new Location(m_scene.RegionInfo.RegionHandle);
69 }
70
71 public void Start()
72 {
73 _listener = new TcpListener(_address, _port);
74 _listener.Start(_backlogAcceptQueueLength);
75 Interlocked.Increment(ref _pendingAccepts);
76 _listener.BeginAcceptSocket(OnAccept, null);
77 }
78
79 private void OnAccept(IAsyncResult ar)
80 {
81 bool beginAcceptCalled = false;
82 try
83 {
84 int count = Interlocked.Decrement(ref _pendingAccepts);
85 if (_shutdown)
86 {
87 if (count == 0)
88 _shutdownEvent.Set();
89 return;
90 }
91 Interlocked.Increment(ref _pendingAccepts);
92 _listener.BeginAcceptSocket(OnAccept, null);
93 beginAcceptCalled = true;
94 Socket socket = _listener.EndAcceptSocket(ar);
95 if (!OnAcceptingSocket(socket))
96 {
97 socket.Disconnect(true);
98 return;
99 }
100 ClientNetworkContext context = new ClientNetworkContext((IPEndPoint) socket.RemoteEndPoint, _port,
101 new NetworkStream(socket), 16384, socket);
102 HttpRequestParser parser;
103 context.BeginRead();
104
105 }
106 catch (Exception err)
107 {
108 if (ExceptionThrown == null)
109#if DEBUG
110 throw;
111#else
112 _logWriter.Write(this, LogPrio.Fatal, err.Message);
113 // we can't really do anything but close the connection
114#endif
115 if (ExceptionThrown != null)
116 ExceptionThrown(this, err);
117
118 if (!beginAcceptCalled)
119 RetryBeginAccept();
120
121 }
122 }
123
124 private void RetryBeginAccept()
125 {
126 try
127 {
128
129 _listener.BeginAcceptSocket(OnAccept, null);
130 }
131 catch (Exception err)
132 {
133
134 if (ExceptionThrown == null)
135#if DEBUG
136 throw;
137#else
138 // we can't really do anything but close the connection
139#endif
140 if (ExceptionThrown != null)
141 ExceptionThrown(this, err);
142 }
143 }
144
145 private bool OnAcceptingSocket(Socket sock)
146 {
147 ClientAcceptedEventArgs args = new ClientAcceptedEventArgs(sock);
148 Accepted(this, args);
149 return !args.Revoked;
150 }
151 /// <summary>
152 /// Catch exceptions not handled by the listener.
153 /// </summary>
154 /// <remarks>
155 /// Exceptions will be thrown during debug mode if this event is not used,
156 /// exceptions will be printed to console and suppressed during release mode.
157 /// </remarks>
158 public event ExceptionHandler ExceptionThrown = delegate { };
159
160
161
162 }
163}