123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using OpenSim.Framework.Servers;
- using Mono.Addins;
- using log4net;
- using Nini.Config;
- using OpenSim.Region.Framework.Interfaces;
- using OpenSim.Region.Framework.Scenes;
- using OpenSim.Framework.Servers.HttpServer;
- namespace OpenSim.Region.OptionalModules.WebSocketEchoModule
- {
-
- [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebSocketEchoModule")]
- public class WebSocketEchoModule : ISharedRegionModule
- {
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private bool enabled;
- public string Name { get { return "WebSocketEchoModule"; } }
- public Type ReplaceableInterface { get { return null; } }
- private HashSet<WebSocketHttpServerHandler> _activeHandlers = new HashSet<WebSocketHttpServerHandler>();
- public void Initialise(IConfigSource pConfig)
- {
- enabled = (pConfig.Configs["WebSocketEcho"] != null);
- // if (enabled)
- // m_log.DebugFormat("[WebSocketEchoModule]: INITIALIZED MODULE");
- }
- /// <summary>
- /// This method sets up the callback to WebSocketHandlerCallback below when a HTTPRequest comes in for /echo
- /// </summary>
- public void PostInitialise()
- {
- if (enabled)
- MainServer.Instance.AddWebSocketHandler("/echo", WebSocketHandlerCallback);
- }
- // This gets called by BaseHttpServer and gives us an opportunity to set things on the WebSocket handler before we turn it on
- public void WebSocketHandlerCallback(string path, WebSocketHttpServerHandler handler)
- {
- SubscribeToEvents(handler);
- handler.SetChunksize(8192);
- handler.NoDelay_TCP_Nagle = true;
- handler.HandshakeAndUpgrade();
- }
- //These are our normal events
- public void SubscribeToEvents(WebSocketHttpServerHandler handler)
- {
- handler.OnClose += HandlerOnOnClose;
- handler.OnText += HandlerOnOnText;
- handler.OnUpgradeCompleted += HandlerOnOnUpgradeCompleted;
- handler.OnData += HandlerOnOnData;
- handler.OnPong += HandlerOnOnPong;
- }
- public void UnSubscribeToEvents(WebSocketHttpServerHandler handler)
- {
- handler.OnClose -= HandlerOnOnClose;
- handler.OnText -= HandlerOnOnText;
- handler.OnUpgradeCompleted -= HandlerOnOnUpgradeCompleted;
- handler.OnData -= HandlerOnOnData;
- handler.OnPong -= HandlerOnOnPong;
- }
- private void HandlerOnOnPong(object sender, PongEventArgs pongdata)
- {
- m_log.Info("[WebSocketEchoModule]: Got a pong.. ping time: " + pongdata.PingResponseMS);
- }
- private void HandlerOnOnData(object sender, WebsocketDataEventArgs data)
- {
- WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler;
- obj.SendData(data.Data);
- m_log.Info("[WebSocketEchoModule]: We received a bunch of ugly non-printable bytes");
- obj.SendPingCheck();
- }
-
- private void HandlerOnOnUpgradeCompleted(object sender, UpgradeCompletedEventArgs completeddata)
- {
- WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler;
- _activeHandlers.Add(obj);
- }
- private void HandlerOnOnText(object sender, WebsocketTextEventArgs text)
- {
- WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler;
- obj.SendMessage(text.Data);
- m_log.Info("[WebSocketEchoModule]: We received this: " + text.Data);
- }
- // Remove the references to our handler
- private void HandlerOnOnClose(object sender, CloseEventArgs closedata)
- {
- WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler;
- UnSubscribeToEvents(obj);
- lock (_activeHandlers)
- _activeHandlers.Remove(obj);
- obj.Dispose();
- }
- // Shutting down.. so shut down all sockets.
- // Note.. this should be done outside of an ienumerable if you're also hook to the close event.
- public void Close()
- {
- if (!enabled)
- return;
-
- // We convert this to a for loop so we're not in in an IEnumerable when the close
- //call triggers an event which then removes item from _activeHandlers that we're enumerating
- WebSocketHttpServerHandler[] items = new WebSocketHttpServerHandler[_activeHandlers.Count];
- _activeHandlers.CopyTo(items);
- for (int i = 0; i < items.Length; i++)
- {
- items[i].Close(string.Empty);
- items[i].Dispose();
- }
- _activeHandlers.Clear();
- MainServer.Instance.RemoveWebSocketHandler("/echo");
- }
- public void AddRegion(Scene scene)
- {
- // m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} ADDED", scene.RegionInfo.RegionName);
- }
- public void RemoveRegion(Scene scene)
- {
- // m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
- }
- public void RegionLoaded(Scene scene)
- {
- // m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} LOADED", scene.RegionInfo.RegionName);
- }
- }
- }
|