123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Threading.Channels;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using ProtoDataBuff;
- using ChatServer.server;
- using Chat;
- namespace ChatServer
- {
- class Program
- {
- const int port = 6000; // 端口号(用来监听的)
- static Socket SocketWatch = null; // 创建一个和客户端通信的套接字
- /// <summary>
- /// peer管理集合
- /// </summary>
- static public Dictionary<string, Peer> Peers = new Dictionary<string, Peer>();
- /// <summary>
- /// 消息分发
- /// </summary>
- private static Dictionary<eProtocalCommand, Action<string, sSocketData>> callbacks = new Dictionary<eProtocalCommand, Action<string, sSocketData>>();
- static void Main(string[] args)
- {
- IPAddress ip = IPAddress.Any;
- IPEndPoint ipe = new IPEndPoint(ip, port); //将IP地址和端口号绑定到网络节点point上
- // callbacks.Add(eProtocalCommand.CsChatLogin, On_Login); // 绑定处理逻辑
- callbacks.Add(eProtocalCommand.CsChatSendMsg, On_SendMessage); // 绑定处理逻辑
- //定义一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议)
- SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- SocketWatch.Bind(ipe); // 监听绑定的网络节点
- SocketWatch.Listen(20); // 将套接字的监听队列长度限制为20
- Console.WriteLine("开启监听......");
- Console.WriteLine("ctrl + c 退出程序......");
- Task.Run(MsgLoop);
- Task.Run(WatchConnecting).Wait();
- Console.ReadLine();
- SocketWatch.Close();
- }
- internal static void AddPeer(Peer p)
- {
- lock (Peers)
- {
- Peers.Add(p.Key, p);
- }
- }
- internal static void RemovePeer(string key)
- {
- lock (Peers)
- {
- Peers.Remove(key);
- }
- }
- /// <summary>
- /// 发送消息
- /// </summary>
- /// <param name="peerId"></param>
- /// <param name="data"></param>
- static void On_SendMessage(string peerKey, sSocketData data)
- {
- if (Peers.TryGetValue(peerKey, out Peer p))
- {
- var msg = CS_ChatSendMsg.Parser.ParseFrom(data._data);
- if (null != msg && msg.Msg.Trim().Length>0)
- {
- var rdb = Redis.Ins.GetDatabase(0);
- var sd = new SC_ChatNewMsg() { FromChannel = msg.ToChannel, SenderName = p.Name, Msg = msg.Msg, SenderUid = p.UID };
- switch (msg.ToChannel)
- {
- case ChatChannel.System: // 这个一般是客户端生成的, 除非是GM号,一般人发送这种消息拒绝转发.
- if (rdb.HashExists(MemKey_Cfg.GM_uids_hash, p.UID))
- {
- Peers.Values.ToList().ForEach(_p => _p.SendEvent(eProtocalCommand.ScChatNewMsg, sd));
- }
- else
- {
- Console.WriteLine($"非GM用户({p.UID})发送了系统消息转发请求!");
- }
- break;
- case ChatChannel.World:
- Peers.Values.ToList().ForEach(_p => _p.SendEvent(eProtocalCommand.ScChatNewMsg, sd));
- break;
- case ChatChannel.Guild:
- if (rdb.HashExists(MemKey_User.Guild(p.UID, p.zoneid), "guildId"))
- {
- var a = rdb.HashGet(MemKey_User.Guild(p.UID, p.zoneid), "guildId").ToString();
- var guildId = int.Parse(a);
- if (guildId > 0)
- {
- JArray jArray = JArray.Parse(rdb.HashGet(MemKey_Game.Guild(p.zoneid, guildId), "members").ToString());
- if (jArray.Count > 0)
- {
- var keys = from j in jArray select j.ToString() + ":" + p.zoneid;
- Peers.Where(kv => keys.Contains(kv.Key)).ToList().ForEach(kv => kv.Value.SendEvent(eProtocalCommand.ScChatNewMsg, sd));
- }
- }
- else
- {
- Console.WriteLine($"找不到用户({p.UID})的公会信息");
- }
- }
- else
- {
- Console.WriteLine($"找不到用户({p.UID})的公会信息");
- }
- break;
- case ChatChannel.Single:
- Peers.Values.Where(peer =>peer.Name == msg.ToNickName).ToList().ForEach(_p => _p.SendEvent(eProtocalCommand.ScChatNewMsg, sd));
- break;
- default:
- Console.WriteLine("chat:未知的发送目标");
- break;
- }
- }
- }
- }
- /// <summary>
- /// 监听客户端发来的请求
- /// </summary>
- async static Task WatchConnecting()
- {
- while (true) // 持续不断监听客户端发来的请求
- {
- Socket connection;
- try
- {
- connection = await SocketWatch.AcceptAsync();
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message); // 提示套接字监听异常
- break;
- }
- var p = new Peer(connection);
- }
- }
- /// <summary>
- /// 客户端消息队列
- /// </summary>
- public static Channel<KeyValuePair<string, sSocketData>> MsgChannel = Channel.CreateBounded<KeyValuePair<string, sSocketData>>(1000);
- static async void MsgLoop()
- {
- while (true)
- {
- var msg = await MsgChannel.Reader.ReadAsync();
- if (callbacks.ContainsKey(msg.Value._protocallType))
- {
- callbacks[msg.Value._protocallType](msg.Key, msg.Value);
- }
- else
- {
- // 未找到消息处理逻辑
- }
- }
- }
- }
- }
|