| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #if !UNITY_WEBGL
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Net;
- using System.Net.WebSockets;
- namespace ET
- {
- public class WService: AService
- {
- private long idGenerater = 200000000;
-
- private HttpListener httpListener;
-
- private readonly Dictionary<long, WChannel> channels = new Dictionary<long, WChannel>();
- public WService(ThreadSynchronizationContext threadSynchronizationContext, IEnumerable<string> prefixs)
- {
- this.ThreadSynchronizationContext = threadSynchronizationContext;
-
- this.httpListener = new HttpListener();
- StartAccept(prefixs).Coroutine();
- }
-
- public WService(ThreadSynchronizationContext threadSynchronizationContext)
- {
- this.ThreadSynchronizationContext = threadSynchronizationContext;
- }
-
- private long GetId
- {
- get
- {
- return ++this.idGenerater;
- }
- }
-
- public WChannel Create(string address, long id)
- {
- ClientWebSocket webSocket = new ClientWebSocket();
- WChannel channel = new WChannel(id, webSocket, address, this);
- this.channels[channel.Id] = channel;
- return channel;
- }
- public override void Remove(long id)
- {
- WChannel channel;
- if (!this.channels.TryGetValue(id, out channel))
- {
- return;
- }
- this.channels.Remove(id);
- channel.Dispose();
- }
- public override bool IsDispose()
- {
- return this.httpListener == null;
- }
- protected void Get(long id, string address)
- {
- if (!this.channels.TryGetValue(id, out _))
- {
- this.Create(address, id);
- }
- }
- public override void Dispose()
- {
- this.ThreadSynchronizationContext = null;
- this.httpListener?.Close();
- this.httpListener = null;
- }
- private async ETTask StartAccept(IEnumerable<string> prefixs)
- {
- try
- {
- foreach (string prefix in prefixs)
- {
- this.httpListener.Prefixes.Add(prefix);
- Log.Console($"start {prefix}");
- }
- httpListener.Start();
- while (true)
- {
- var context = await this.httpListener.GetContextAsync();
- Log.Info($"Accept WebSocket {context.Request.RemoteEndPoint}");
- //跨域设置
- {
- context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
- context.Response.AddHeader("Access-Control-Allow-Headers", "content-type, Signature, Timestamp, Token");
- context.Response.AddHeader("Access-Control-Allow-Methods", "POST");
- context.Response.AddHeader("Access-Control-Allow-Origin", "*");
- if (context.Request.HttpMethod == "OPTIONS")
- {
- context.Response.StatusCode = 204;
- }
- }
- if (context.Request.IsWebSocketRequest)
- {
- var webSocket = await context.AcceptWebSocketAsync(null);
- WChannel channel = new WChannel(this.GetId, webSocket.WebSocket, this, context.Request.RemoteEndPoint);
- this.channels[channel.Id] = channel;
- this.OnAccept(channel.Id, channel.RemoteAddress);
- }
- else
- {
- context.Response.StatusCode = 400;
- context.Response.Close();
- }
- }
- }
- catch (HttpListenerException e)
- {
- if (e.ErrorCode == 5)
- {
- throw new Exception($"CMD管理员中输入: netsh http add urlacl url=http://{string.Join(",", prefixs)}/ user=Everyone", e);
- }
- Log.Error(e);
- }
- catch (Exception e)
- {
- Log.Error(e);
- }
- }
-
- protected override void Get(long id, IPEndPoint address)
- {
- // 将IPEndPoint转换为WebSocket适用的地址格式(ws://或wss://)
- string webSocketAddress = $"ws://{address.Address}:{address.Port}";
- // 检查是否已存在该通道
- if (!this.channels.TryGetValue(id, out _))
- {
- // 不存在则创建新的WebSocket连接
- this.Create(webSocketAddress, id);
- } }
- protected override void Send(long channelId, long actorId, MemoryStream stream)
- {
- this.channels.TryGetValue(channelId, out WChannel channel);
- if (channel == null)
- {
- return;
- }
- channel.Send(stream);
- }
- public override void Update()
- {
- }
- }
- }
- #endif
|