#region License /* * WebSocketService.cs * * The MIT License * * Copyright (c) 2012-2014 sta.blockhead * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #endregion using System; using System.IO; using WebSocketSharp.Net; using WebSocketSharp.Net.WebSockets; namespace WebSocketSharp.Server { /// /// Provides the basic functions of the WebSocket service provided by the /// or . /// /// /// The WebSocketService class is an abstract class. /// public abstract class WebSocketService : IWebSocketSession { #region Private Fields private WebSocketContext _context; private string _protocol; private WebSocketSessionManager _sessions; private DateTime _start; private WebSocket _websocket; #endregion #region Protected Constructors /// /// Initializes a new instance of the class. /// protected WebSocketService () { _start = DateTime.MaxValue; } #endregion #region Protected Properties /// /// Gets or sets the logging functions. /// /// /// If you want to change the current logger to the service own logger, you /// set this property to a new instance that you created. /// /// /// A that provides the logging functions. /// protected Logger Log { get { return _websocket != null ? _websocket.Log : null; } set { if (_websocket != null) _websocket.Log = value; } } /// /// Gets the manager of the sessions to the WebSocket service. /// /// /// A that manages the sessions to the /// WebSocket service. /// protected WebSocketSessionManager Sessions { get { return _sessions; } } #endregion #region Public Properties /// /// Gets the WebSocket connection request information. /// /// /// A that represents the WebSocket connection /// request. /// public WebSocketContext Context { get { return _context; } } /// /// Gets the unique ID of the current instance. /// /// /// A that represents the unique ID of the current /// instance. /// public string ID { get; private set; } /// /// Gets or sets the subprotocol used on the WebSocket connection. /// /// /// Set operation of this property is available before the connection has /// been established. /// /// /// /// A that represents the subprotocol if any. /// /// /// The value to set must be a token defined in /// RFC 2616. /// /// /// The default value is . /// /// public string Protocol { get { return _websocket != null ? _websocket.Protocol : _protocol ?? String.Empty; } set { if (State == WebSocketState.CONNECTING && value.IsToken ()) _protocol = value; } } /// /// Gets the time that the current instance /// has been started. /// /// /// A that represents the time that the current /// instance has been started. /// public DateTime StartTime { get { return _start; } } /// /// Gets the state of the WebSocket connection. /// /// /// One of the values that indicate the state of /// the WebSocket connection. /// public WebSocketState State { get { return _websocket != null ? _websocket.ReadyState : WebSocketState.CONNECTING; } } #endregion #region Private Methods private void onClose (object sender, CloseEventArgs e) { if (ID == null) return; _sessions.Remove (ID); OnClose (e); } private void onError (object sender, ErrorEventArgs e) { OnError (e); } private void onMessage (object sender, MessageEventArgs e) { OnMessage (e); } private void onOpen (object sender, EventArgs e) { ID = _sessions.Add (this); if (ID == null) { _websocket.Close (CloseStatusCode.AWAY); return; } _start = DateTime.Now; OnOpen (); } #endregion #region Internal Methods internal void Start (WebSocketContext context, WebSocketSessionManager sessions) { _context = context; _sessions = sessions; _websocket = context.WebSocket; _websocket.Protocol = _protocol; _websocket.CookiesValidation = ValidateCookies; _websocket.OnOpen += onOpen; _websocket.OnMessage += onMessage; _websocket.OnError += onError; _websocket.OnClose += onClose; _websocket.ConnectAsServer (); } #endregion #region Protected Methods /// /// Calls the method with the specified /// . /// /// /// A that represents the error message. /// protected void Error (string message) { if (message != null && message.Length > 0) OnError (new ErrorEventArgs (message)); } /// /// Is called when the WebSocket connection has been closed. /// /// /// A that contains the event data associated /// with an inner event. /// protected virtual void OnClose (CloseEventArgs e) { } /// /// Is called when the inner or current /// gets an error. /// /// /// An that contains the event data associated /// with an inner event. /// protected virtual void OnError (ErrorEventArgs e) { } /// /// Is called when the inner receives a data frame. /// /// /// A that contains the event data associated /// with an inner event. /// protected virtual void OnMessage (MessageEventArgs e) { } /// /// Is called when the WebSocket connection has been established. /// protected virtual void OnOpen () { } /// /// Sends a binary to the client on the current /// session in the WebSocket service. /// /// /// An array of that represents the binary data to send. /// protected void Send (byte [] data) { if (_websocket != null) _websocket.Send (data); } /// /// Sends the specified as a binary data /// to the client on the current session in the WebSocket service. /// /// /// A that represents the file to send. /// protected void Send (FileInfo file) { if (_websocket != null) _websocket.Send (file); } /// /// Sends a text to the client on the current /// session in the WebSocket service. /// /// /// A that represents the text data to send. /// protected void Send (string data) { if (_websocket != null) _websocket.Send (data); } /// /// Sends a binary asynchronously to the client /// on the current session in the WebSocket service. /// /// /// This method doesn't wait for the send to be complete. /// /// /// An array of that represents the binary data to send. /// /// /// An Action<bool> delegate that references the method(s) called when /// the send is complete. A passed to this delegate is /// true if the send is complete successfully; otherwise, false. /// protected void SendAsync (byte [] data, Action completed) { if (_websocket != null) _websocket.SendAsync (data, completed); } /// /// Sends the specified as a binary data /// asynchronously to the client on the current session in the WebSocket /// service. /// /// /// This method doesn't wait for the send to be complete. /// /// /// A that represents the file to send. /// /// /// An Action<bool> delegate that references the method(s) called when /// the send is complete. A passed to this delegate is /// true if the send is complete successfully; otherwise, false. /// protected void SendAsync (FileInfo file, Action completed) { if (_websocket != null) _websocket.SendAsync (file, completed); } /// /// Sends a text asynchronously to the client /// on the current session in the WebSocket service. /// /// /// This method doesn't wait for the send to be complete. /// /// /// A that represents the text data to send. /// /// /// An Action<bool> delegate that references the method(s) called when /// the send is complete. A passed to this delegate is /// true if the send is complete successfully; otherwise, false. /// protected void SendAsync (string data, Action completed) { if (_websocket != null) _websocket.SendAsync (data, completed); } /// /// Sends a binary data from the specified asynchronously /// to the client on the current session in the WebSocket service. /// /// /// This method doesn't wait for the send to be complete. /// /// /// A from which contains the binary data to send. /// /// /// An that represents the number of bytes to send. /// /// /// An Action<bool> delegate that references the method(s) called when /// the send is complete. A passed to this delegate is /// true if the send is complete successfully; otherwise, false. /// protected void SendAsync (Stream stream, int length, Action completed) { if (_websocket != null) _websocket.SendAsync (stream, length, completed); } /// /// Validates the HTTP Cookies used in the WebSocket connection request. /// /// /// This method is called when the inner validates /// the WebSocket connection request. /// /// /// true if the cookies is valid; otherwise, false. This method /// returns true as default. /// /// /// A that contains the collection of the /// cookies to validate. /// /// /// A that receives the cookies to send to the /// client. /// protected virtual bool ValidateCookies ( CookieCollection request, CookieCollection response) { return true; } #endregion } }