123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- using System;
- using System.Net;
- using System.Text;
- namespace NetCoreServer
- {
- /// <summary>
- /// WebSocket server
- /// </summary>
- /// <remarks> WebSocket server is used to communicate with clients using WebSocket protocol. Thread-safe.</remarks>
- public class WsServer : HttpServer, IWebSocket
- {
- internal readonly WebSocket WebSocket;
- /// <summary>
- /// Initialize WebSocket server with a given IP address and port number
- /// </summary>
- /// <param name="address">IP address</param>
- /// <param name="port">Port number</param>
- public WsServer(IPAddress address, int port) : base(address, port) { WebSocket = new WebSocket(this); }
- /// <summary>
- /// Initialize WebSocket server with a given IP address and port number
- /// </summary>
- /// <param name="address">IP address</param>
- /// <param name="port">Port number</param>
- public WsServer(string address, int port) : base(address, port) { WebSocket = new WebSocket(this); }
- /// <summary>
- /// Initialize WebSocket server with a given DNS endpoint
- /// </summary>
- /// <param name="endpoint">DNS endpoint</param>
- public WsServer(DnsEndPoint endpoint) : base(endpoint) { WebSocket = new WebSocket(this); }
- /// <summary>
- /// Initialize WebSocket server with a given IP endpoint
- /// </summary>
- /// <param name="endpoint">IP endpoint</param>
- public WsServer(IPEndPoint endpoint) : base(endpoint) { WebSocket = new WebSocket(this); }
- #region Session management
- public virtual bool CloseAll() => CloseAll(0, Span<byte>.Empty);
- public virtual bool CloseAll(int status) => CloseAll(status, Span<byte>.Empty);
- public virtual bool CloseAll(int status, string text) => CloseAll(status, Encoding.UTF8.GetBytes(text));
- public virtual bool CloseAll(int status, ReadOnlySpan<char> text) => CloseAll(status, Encoding.UTF8.GetBytes(text.ToArray()));
- public virtual bool CloseAll(int status, byte[] buffer) => CloseAll(status, buffer.AsSpan());
- public virtual bool CloseAll(int status, byte[] buffer, long offset, long size) => CloseAll(status, buffer.AsSpan((int)offset, (int)size));
- public virtual bool CloseAll(int status, ReadOnlySpan<byte> buffer)
- {
- lock (WebSocket.WsSendLock)
- {
- WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, status);
- if (!Multicast(WebSocket.WsSendBuffer.AsSpan()))
- return false;
- return base.DisconnectAll();
- }
- }
- #endregion
- #region Multicasting
- public override bool Multicast(ReadOnlySpan<byte> buffer)
- {
- if (!IsStarted)
- return false;
- if (buffer.IsEmpty)
- return true;
- // Multicast data to all WebSocket sessions
- foreach (var session in Sessions.Values)
- {
- if (session is WsSession wsSession)
- {
- if (wsSession.WebSocket.WsHandshaked)
- wsSession.SendAsync(buffer);
- }
- }
- return true;
- }
- #endregion
- #region WebSocket multicast text methods
- public bool MulticastText(string text) => MulticastText(Encoding.UTF8.GetBytes(text));
- public bool MulticastText(ReadOnlySpan<char> text) => MulticastText(Encoding.UTF8.GetBytes(text.ToArray()));
- public bool MulticastText(byte[] buffer) => MulticastText(buffer.AsSpan());
- public bool MulticastText(byte[] buffer, long offset, long size) => MulticastText(buffer.AsSpan((int)offset, (int)size));
- public bool MulticastText(ReadOnlySpan<byte> buffer)
- {
- lock (WebSocket.WsSendLock)
- {
- WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer);
- return Multicast(WebSocket.WsSendBuffer.AsSpan());
- }
- }
- #endregion
- #region WebSocket multicast binary methods
- public bool MulticastBinary(string text) => MulticastBinary(Encoding.UTF8.GetBytes(text));
- public bool MulticastBinary(ReadOnlySpan<char> text) => MulticastBinary(Encoding.UTF8.GetBytes(text.ToArray()));
- public bool MulticastBinary(byte[] buffer) => MulticastBinary(buffer.AsSpan());
- public bool MulticastBinary(byte[] buffer, long offset, long size) => MulticastBinary(buffer.AsSpan((int)offset, (int)size));
- public bool MulticastBinary(ReadOnlySpan<byte> buffer)
- {
- lock (WebSocket.WsSendLock)
- {
- WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer);
- return Multicast(WebSocket.WsSendBuffer.AsSpan());
- }
- }
- #endregion
- #region WebSocket multicast ping methods
- public bool MulticastPing(string text) => MulticastPing(Encoding.UTF8.GetBytes(text));
- public bool MulticastPing(ReadOnlySpan<char> text) => MulticastPing(Encoding.UTF8.GetBytes(text.ToArray()));
- public bool MulticastPing(byte[] buffer) => MulticastPing(buffer.AsSpan());
- public bool MulticastPing(byte[] buffer, long offset, long size) => MulticastPing(buffer.AsSpan((int)offset, (int)size));
- public bool MulticastPing(ReadOnlySpan<byte> buffer)
- {
- lock (WebSocket.WsSendLock)
- {
- WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer);
- return Multicast(WebSocket.WsSendBuffer.AsSpan());
- }
- }
- #endregion
- protected override TcpSession CreateSession() { return new WsSession(this); }
- }
- }
|