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; // 创建一个和客户端通信的套接字
///
/// peer管理集合
///
static public Dictionary Peers = new Dictionary();
///
/// 消息分发
///
private static Dictionary> callbacks = new Dictionary>();
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);
}
}
///
/// 发送消息
///
///
///
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;
}
}
}
}
///
/// 监听客户端发来的请求
///
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);
}
}
///
/// 客户端消息队列
///
public static Channel> MsgChannel = Channel.CreateBounded>(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
{
// 未找到消息处理逻辑
}
}
}
}
}