WeaveSocket框架-Unity太空大战游戏-服务端-1(换成Markdown富文本重写,之前排版有点乱)
服务端项目结构
主要技术架构
Socket框架【WeaveSocket】 及其扩展项目
https://gitee.com/dreamsfly900/universal-Data-Communication-System-for-windows/
数据库【LiteDB】(3.1.4.0)
http://www.litedb.org/
界面UI【WPF】(.Net4.5)
服务端启动类为MyTCPCloud里面的WeaveTCPcloud这个类,用于根据传入的参数,启动服务器监听Socket请求
代码如下:
using MyTcpCommandLibrary;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Reflection;
using System.Xml;
using WeaveBase;
using WeaveSocketServer;
namespace MyTCPCloud
{
public class WeaveTCPcloud : IWeaveUniversal
{
public event WeaveLogDelegate WeaveLogEvent;
public event WeaveServerReceiveSocketMessageCallBack WeaveServerReceiveSocketMessageCallBackEvent;
public event WeaveServerDeleteSocketCallBack WeaveServerDeleteSocketCallBackEvent;
public event WeaveServerUpdateSocketCallBack WeaveServerUpdateSocketCallBackEvent;
public event WeaveServerReceiveOnLineUnityPlayerMessageCallBack WeaveServerReceiveOnLineUnityPlayerMessageCallBackEvent;
public event WeaveServerGetUnityPlayerOnLineCallBack WeaveServerGetUnityPlayerOnLineCallBackEvent;
public event WeaveServerGetUnityPlayerOffLineCallBack WeaveServerGetUnityPlayerOffLineCallBackEvent;
//public XmlDocument xml
//{
// get;set;
//}
public List<WeaveTCPCommandItem> weaveTCPCommandItems
{
get
{
return _weaveTCPCommandItems;
}
set
{
_weaveTCPCommandItems = value;
}
}
public WeaveTable weaveTable
{
get
{
return _weaveTable;
}
set
{
_weaveTable = value;
}
}
public List<WeaveOnLine> weaveOnline
{
get
{
return _weaveOnline;
}
set
{
_weaveOnline = value;
}
}
public List<UnityPlayerOnClient> unityPlayerOnClientList
{
get
{
return _unityPlayerOnClientList;
}
set
{
_unityPlayerOnClientList = value;
}
}
// public IWeaveTcpBase P2Server
public WeaveP2Server P2Server
{
get;set;
}
public WeaveTcpToken TcpToken
{
get
{
return _TcpToken;
}
set
{
_TcpToken = value;
}
}
List<WeaveTCPCommandItem> _weaveTCPCommandItems = new List<WeaveTCPCommandItem>();
WeaveTable _weaveTable = new WeaveTable();
List<WeaveOnLine> _weaveOnline = new List<WeaveOnLine>();
WeaveTcpToken _TcpToken = new WeaveTcpToken();
//我写的方法
List<UnityPlayerOnClient> _unityPlayerOnClientList = new List<UnityPlayerOnClient>();
public bool Run(WevaeSocketSession myI)
{
//ReloadFlies();
AddMyTcpCommandLibrary();
weaveTable.Add("onlinetoken", weaveOnline);//初始化一个队列,记录在线人员的token
if (WeaveLogEvent != null)
WeaveLogEvent("连接", "连接启动成功");
return true;
}
/// <summary>
/// 读取WeavePortTypeEnum类型后,初始化 new WeaveP2Server("127.0.0.1"),并添加端口;
/// </summary>
/// <param name="WeaveServerPort"></param>
public void StartServer(WeaveServerPort _ServerPort)
{
P2Server = new WeaveP2Server("127.0.0.1");
P2Server.waveReceiveEvent += P2ServerReceiveHander;
P2Server.weaveUpdateSocketListEvent += P2ServerUpdateSocketHander;
P2Server.weaveDeleteSocketListEvent += P2ServerDeleteSocketHander;
P2Server.Start( _ServerPort.Port );
TcpToken.PortType = _ServerPort.PortType;
TcpToken.P2Server = P2Server;
TcpToken.IsToken = _ServerPort.IsToken;
TcpToken.WPTE = _ServerPort.PortType;
}
public void AddMyTcpCommandLibrary()
{
try
{
LoginManageCommand loginCmd = new LoginManageCommand();
loginCmd.ServerLoginOKEvent += OnUnityPlayerLoginOK;
AddCmdWorkItems(loginCmd);
AddCmdWorkItems(new GameScoreCommand());
AddCmdWorkItems(new ClientDisConnectedCommand());
}
catch
{
}
}
private void OnUnityPlayerLoginOK(string _u, Socket _socket)
{
WeaveOnLine onLineSocket = weaveOnline.Find(w => w.Socket == _socket);
// throw new NotImplementedException();
UnityPlayerOnClient gamer = new UnityPlayerOnClient()
{
UserName = _u,
isLogin = true,
Name = onLineSocket.Name,
Obj =onLineSocket.Obj,
Socket = _socket,
Token = onLineSocket.Token
};
WeaveServerGetUnityPlayerOnLineCallBackEvent(gamer);
}
public bool CheckIsOnLinePlayerMessage(Socket _socket)
{
WeaveOnLine onLineSocket = weaveOnline.Find(w => w.Socket == _socket);
if (unityPlayerOnClientList.Count == 0)
return false;
else
{
UnityPlayerOnClient player = unityPlayerOnClientList.Find(u => u.Name == onLineSocket.Name);
if (player != null)
return true;
else
return false;
}
}
public void Check_ReceiveMessageCallBackEvent(byte command, string data, Socket _socket)
{
if(CheckIsOnLinePlayerMessage(_socket))
{
UnityPlayerOnClient player = unityPlayerOnClientList.Find(u => u.Socket == _socket);
WeaveServerReceiveOnLineUnityPlayerMessageCallBackEvent(command, data, player);
}
else
{
WeaveOnLine onLine = weaveOnline.Find(w => w.Socket == _socket);
WeaveServerReceiveSocketMessageCallBackEvent( command, data, onLine);
}
}
public void AddCmdWorkItems(WeaveTCPCommand cmd)
{
cmd.SetGlobalQueueTable(weaveTable, TcpToken);
WeaveTCPCommandItem cmdItem = new WeaveTCPCommandItem();
// Ic.SetGlobalQueueTable(weaveTable, TcpTokenList);
cmdItem.WeaveTcpCmd = cmd;
cmdItem.CmdName = cmd.Getcommand();
GetAttributeInfo(cmd, cmd.GetType(), cmd);
weaveTCPCommandItems.Add(cmdItem);
}
public void GetAttributeInfo(WeaveTCPCommand Ic, Type t, object obj)
{
foreach (MethodInfo mi in t.GetMethods())
{
InstallFunAttribute myattribute = (InstallFunAttribute)Attribute.GetCustomAttribute(mi, typeof(InstallFunAttribute));
if (myattribute == null)
{
}
else
{
if (myattribute.Dtu)
{
Delegate del = Delegate.CreateDelegate(typeof(WeaveRequestDataDtuDelegate), obj, mi, true);
Ic.Bm.AddListen(mi.Name, del as WeaveRequestDataDtuDelegate, myattribute.Type, true);
}
else
{
Delegate del = Delegate.CreateDelegate(typeof(WeaveRequestDataDelegate), obj, mi, true);
Ic.Bm.AddListen(mi.Name, del as WeaveRequestDataDelegate, myattribute.Type);
}
}
}
}
void P2ServerUpdateSocketHander(System.Net.Sockets.Socket soc)
{
CallWeaveServerUpdateSocketCallBackEvent(soc);
CallWeaveTCPCommandClassUpdateSocketEvent(soc);
WeaveTcpToken token = TcpToken;
{
if (token.IsToken)
{
//生成一个token,后缀带随机数
string Token = DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(1000, 9999);// EncryptDES(clientipe.Address.ToString() + "|" + DateTime.Now.ToString(), "lllssscc");
if (token.P2Server.Port == ((System.Net.IPEndPoint)soc.LocalEndPoint).Port)
{
//向客户端发送生成的token
bool sendok = false;
if (token.PortType == WeavePortTypeEnum.Bytes)
sendok = token.P2Server.Send(soc, 0xff, token.BytesDataparsing.Get_ByteBystring("token|" + Token + ""));
else
sendok = token.P2Server.Send(soc, 0xff, "token|" + Token + "");
#region if(sendok) 如果发送token成功
if (sendok)
{
WeaveOnLine onLine = CreatWeaveOnLine(Token, soc);
AddWeaveOnLine(onLine);
ForeachWeaveExecuteRuncommandMethod(onLine);
return;
}
#endregion
}
}
else
{
WeaveOnLine online = CreatWeaveOnLine(soc);
weaveOnline.Add(online);
}
}
}
void P2ServerDeleteSocketHander(System.Net.Sockets.Socket soc)
{
CallWeaveServerDeleteSocketCallBackEvent(soc);
// WeaveServerGetUnityPlayerOffLineCallBackEvent()
CallWeaveServerGetUnityPlayerOffLineCallBackEvent(soc);
CallWeaveTCPCommandClassDeleteSocketEvent(soc);
WeaveExecuteRuncommandMethod_Tokenout_RemoveWeaveOnline(soc);
}
void P2ServerReceiveHander(byte command, string data, System.Net.Sockets.Socket soc)
{
//这里待定判定,,是登陆用户的 还是,,,原始Socket发过来的,,来判定执行不同的事件
//普通Socket数据接收事件,还是 登陆的Unity客户端发过来的数据,进入数据接收处理事件
Check_ReceiveMessageCallBackEvent(command, data, soc);
//客户端 登陆 事件要 在这里执行
//客户端 登陆的 Unity用户发来的消息 会 在这里执行
if(command == (byte)CommandEnum.ClientSendDisConnected)
{
P2Server.CliendSendDisConnectedEvent(soc);
return;
}
try
{
if (command == 0xff)
{
//如果是网关command 发过来的 命名,那么执行下面的
WeaveExecuteRuncommandMethod(command, data, soc);
try
{
string[] temp = data.Split('|');
if (temp[0] == "in")
{
WeaveAddOnLineTokenIn(temp[1] , soc);
return;
}
else if (temp[0] == "Restart")
{
RestartWeaveOnLineSocket(temp[1], soc);
}
else if (temp[0] == "out")
{
WeaveExecuteTokenoutMethod(temp[1]);
////移出onlinetoken
}
}
catch
{
}
return;
}
else
WeaveExecuteRunMethod(command, data, soc);
}
catch
{
return;
}
}
public void CallWeaveServerUpdateSocketCallBackEvent(Socket _soc)
{
WeaveOnLine online = weaveOnline.Find(s => s.Socket == _soc);
if (online == null)
{
WeaveOnLine temponline = CreatWeaveOnLine(_soc);
WeaveServerUpdateSocketCallBackEvent(temponline);
}
else
{
WeaveServerUpdateSocketCallBackEvent(online);
}
}
public void CallWeaveServerDeleteSocketCallBackEvent(Socket _soc)
{
WeaveOnLine online = weaveOnline.Find(s => s.Socket == _soc);
if(online !=null)
WeaveServerDeleteSocketCallBackEvent(online);
}
public void CallWeaveServerGetUnityPlayerOffLineCallBackEvent(Socket _soc)
{
UnityPlayerOnClient unitygm = unityPlayerOnClientList.Find(p => p.Socket == _soc);
WeaveServerGetUnityPlayerOffLineCallBackEvent(unitygm);
}
public void WeaveExecuteRuncommandMethod_Tokenout_RemoveWeaveOnline(Socket _soc)
{
try
{
int count = weaveOnline.Count;
WeaveOnLine[] ols = new WeaveOnLine[count];
weaveOnline.CopyTo(0, ols, 0, count);
foreach (WeaveOnLine ol in ols)
{
if (ol.Socket.Equals(_soc))
{
foreach (WeaveTCPCommandItem weaveTCPCommandItem in weaveTCPCommandItems)
{
try
{
WeaveExecuteRuncommandMethod(0xff, "out|" + ol.Token, ol.Socket);
weaveTCPCommandItem.WeaveTcpCmd.Tokenout(ol);
}
catch (Exception ex)
{
if (WeaveLogEvent != null)
WeaveLogEvent("Tokenout", ex.Message);
}
}
weaveOnline.Remove(ol);
return;
}
}
}
catch { }
}
public void CallWeaveTCPCommandClassDeleteSocketEvent(Socket soc)
{
try
{
int count = weaveTCPCommandItems.Count;
WeaveTCPCommandItem[] commandlist = new WeaveTCPCommandItem[count];
weaveTCPCommandItems.CopyTo(0, commandlist, 0, count);
foreach (WeaveTCPCommandItem weaveTCPCommandItem in commandlist)
{
try
{
weaveTCPCommandItem.WeaveTcpCmd.WeaveDeleteSocketEvent(soc);
}
catch (Exception ex)
{
if (WeaveLogEvent != null)
WeaveLogEvent("EventDeleteConnSoc", ex.Message);
}
}
}
catch { }
}
public void CallWeaveTCPCommandClassUpdateSocketEvent(Socket soc)
{
try
{
int count = weaveTCPCommandItems.Count;
WeaveTCPCommandItem[] commandlist = new WeaveTCPCommandItem[count];
weaveTCPCommandItems.CopyTo(0, commandlist, 0, count);
foreach (WeaveTCPCommandItem weaveTCPCommandItem in commandlist)
{
try
{
weaveTCPCommandItem.WeaveTcpCmd.WeaveUpdateSocketEvent(soc);
}
catch (Exception ex)
{
if (WeaveLogEvent != null)
WeaveLogEvent("EventUpdataConnSoc", ex.Message);
}
}
}
catch
{
}
}
public void ForeachWeaveExecuteRuncommandMethod(WeaveOnLine onLine)
{
foreach (WeaveTCPCommandItem cmdItem in weaveTCPCommandItems)
{
try
{
WeaveExecuteRuncommandMethod(0xff, "in|" + onLine.Token, onLine.Socket);
cmdItem.WeaveTcpCmd.TokenIn(onLine);
}
catch (Exception ex)
{
if (WeaveLogEvent != null)
WeaveLogEvent("Tokenin", ex.Message);
}
}
}
/// <summary>
/// 执行继承自WeaveTCPCommand类里面的Runcommand方法
/// </summary>
/// <param name="command"></param>
/// <param name="data"></param>
/// <param name="soc"></param>
public void WeaveExecuteRuncommandMethod(byte command, string data, System.Net.Sockets.Socket soc)
{
foreach (WeaveTCPCommandItem cmd in weaveTCPCommandItems)
{
try
{
cmd.WeaveTcpCmd.Runcommand(command, data, soc);
}
catch (Exception ex)
{
WeaveLogEvent?.Invoke("receiveevent", ex.Message);
}
}
}
/// <summary>
/// 不是0xff这个command发来的...命令
/// </summary>
/// <param name="command"></param>
/// <param name="data"></param>
/// <param name="soc"></param>
public void WeaveExecuteRunMethod(byte command, string data, System.Net.Sockets.Socket soc)
{
foreach (WeaveTCPCommandItem cmd in weaveTCPCommandItems)
{
if (cmd.CmdName == command)
{
try
{
cmd.WeaveTcpCmd.Run(data, soc);
cmd.WeaveTcpCmd.RunBase(data, soc);
}
catch (Exception ex)
{
WeaveLogEvent?.Invoke("receiveevent", ex.Message);
}
}
}
}
public void WeaveExecuteTokenoutMethod(string _token)
{
////移出onlinetoken
int count = weaveOnline.Count;
WeaveOnLine[] ols = new WeaveOnLine[count];
weaveOnline.CopyTo(0, ols, 0, count);
foreach (WeaveOnLine onlinesession in ols)
{
if (onlinesession.Token == _token)//temp[1])
{
foreach (WeaveTCPCommandItem cmdItem in weaveTCPCommandItems)
{
try
{
cmdItem.WeaveTcpCmd.Tokenout(onlinesession);
}
catch (Exception ex)
{
WeaveLogEvent?.Invoke("Tokenout", ex.Message);
}
}
weaveOnline.Remove(onlinesession);
return;
}
}
}
public void RestartWeaveOnLineSocket(string _s , Socket _soc)
{
int count = weaveOnline.Count;
WeaveOnLine[] ols = new WeaveOnLine[count];
weaveOnline.CopyTo(0, ols, 0, count);
string IPport = ((System.Net.IPEndPoint)_soc.RemoteEndPoint).Address.ToString() + ":" + _s;// temp[1];
foreach (WeaveOnLine ol in ols)
{
try
{
if (ol.Socket != null)
{
String IP = ((System.Net.IPEndPoint)ol.Socket.RemoteEndPoint).Address.ToString() + ":" + ((System.Net.IPEndPoint)ol.Socket.RemoteEndPoint).Port;
if (IP == IPport)
{
ol.Socket = _soc;
}
}
}
catch { }
}
}
public void WeaveAddOnLineTokenIn(string _s , Socket soc)
{
WeaveOnLine ol = new WeaveOnLine();
ol.Token = _s;
ol.Socket = soc;
weaveOnline.Add(ol);
foreach (WeaveTCPCommandItem weaveTCPCommandItem in weaveTCPCommandItems)
{
try
{
weaveTCPCommandItem.WeaveTcpCmd.TokenIn(ol);
}
catch (Exception ex)
{
WeaveLogEvent?.Invoke("Tokenin", ex.Message);
}
}
}
public WeaveOnLine CreatWeaveOnLine(Socket _socket)
{
WeaveOnLine ol = new WeaveOnLine()
{
Name = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
Obj = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
Socket = _socket,
Token = DateTime.Now.ToString("yyyyMMddHHmmssfff")
};
return ol;
}
public WeaveOnLine CreatWeaveOnLine(string _token,Socket _socket)
{
WeaveOnLine ol = new WeaveOnLine()
{
Name = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
Obj = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
Socket = _socket,
Token = _token
};
return ol;
}
public UnityPlayerOnClient ConvertWeaveOnlineToUnityPlayerOnClient(WeaveOnLine wonline)
{
UnityPlayerOnClient uplayer = new UnityPlayerOnClient()
{
Obj = wonline.Obj,
Socket = wonline.Socket,
Token = wonline.Token,
Name = wonline.Name
};
return uplayer;
}
public void DeleteUnityPlayerOnClient(Socket osc)
{
try
{
if (unityPlayerOnClientList.Count > 0)
unityPlayerOnClientList.Remove(unityPlayerOnClientList.Find(u => u.Socket == osc));
}
catch
{
}
}
public void AddUnityPlayerClient_CheckSameItem(UnityPlayerOnClient item ,string itemName)
{
System.Threading.Thread.Sleep(500);
lock (this)
{
if (unityPlayerOnClientList.Find(i => i.Name == itemName) != null)
return;
else
unityPlayerOnClientList.Add(item);
}
}
public void AddWeaveOnLine(WeaveOnLine item)
{
WeaveOnLine hasOnline = weaveOnline.Find(w => w.Name == item.Name);
{
if (hasOnline != null)
{
weaveOnline.Remove(hasOnline);
//添加修改参数后的WeaveOnLine
weaveOnline.Add(item);
}
else
{
weaveOnline.Add(item);
}
}
}
}
}
重点说下AddMyTcpCommandLibrary方法
这个方法加载了MyTcpCommandLibrary项目下的几个继承自WeaveTCPCommand的类,用于接收客户端发过来的数据中,对应第一位byte,于它里面的GetCommand()方法返回的 一位byte命名对应
public class LoginManageCommand : WeaveTCPCommand
{
public override byte Getcommand()
{
//此CLASS的实例,代表的指令,指令从0-254,0x9c与0xff为内部指令不能使用。
//0x01的意思是,只要是客户端发过来的数据第一位byte为0x01,那么会进入本实例进行处理
//return 0x01;
return (byte)CommandEnum.ClientSendLoginModel;
}
//其它代码 .................
[InstallFun("forever")]
public void CheckLogin(Socket soc, WeaveSession wsession)
{
//执行查找数据的操作......等代码
}
}
例如客户端调用框架(客户端也需使用框架)的如下方法发送数据
weaveSocketGameClient.SendRoot<Model>((byte)CommandEnum.ClientSendLoginModel, "CheckLogin", m , 0);
则会进入LoginManageCommand这个类的CheckLogin方法中进行处理
在看前端WPF-UI使用的实例代码,实例化WeaveTCPcloud,传入相关参数,请监听相关事件,启动服务器
简单说一下几个事件
WeaveServerUpdateSocketCallBackEvent 当有Socket连接到服务器的事件
WeaveServerReceiveSocketMessageCallBackEvent 当有数据从远端Socket发送到服务器的事件(这里没有验证Unity3D客户端的状态,属于UnityPlayerOffLine状态,没有上线,数据发来,在这里接收处理)
WeaveServerDeleteSocketCallBackEvent 当有Socket断开连接的事件
WeaveServerGetUnityPlayerOnLineCallBackEvent 当有Socket(已经连上)发送完账号密码,服务器认证了,生成了一个UnityPlayerOnLine对象的的事件,用于确定登陆上线成功后的玩家的身份
WeaveServerGetUnityPlayerOffLineCallBackEvent 当有Socket(已经连上)并已经上限的玩家,退出游戏,断开连接的事件
WeaveServerReceiveOnLineUnityPlayerMessageCallBackEvent 当有数据从远端Socket发送到服务器的事件(这里的数据是由已经登陆成功上线的Unity3D客户端发来的)事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WeaveBase;
using System.Net.Sockets;
using MyTCPCloud;
using System.Windows.Threading;
namespace WeavingSocketServerWPF
{
/// <summary>
/// MyUnityServer.xaml 的交互逻辑
/// </summary>
public partial class MyUnityServer : Window
{
public MyUnityServer()
{
InitializeComponent();
// DispatcherFunction();
}
/// <summary>
/// 监听端口列表,,可以选择监听多个端口
/// </summary>
WeaveServerPort wserverport = new WeaveServerPort();
WeaveTCPcloud weaveTCPcloud = new WeaveTCPcloud();
List<MyListBoxItem> loginedUserList = new List<MyListBoxItem>();
List<MyListBoxItem> connectedSocketItemList = new List<MyListBoxItem>();
// DispatcherTimer dispatcherTimer = new DispatcherTimer();
private void StartListen_button_Click(object sender, RoutedEventArgs e)
{
//设置登陆后的用户列表Listbox的数据源
LoginedUser_listBox.ItemsSource = loginedUserList;
//设置连接到服务器的Socket列表的Listbox的数据源
ConnectedSocket_listBox.ItemsSource = connectedSocketItemList;
WevaeSocketSession mif = new WevaeSocketSession();
weaveTCPcloud.Run(mif);
wserverport.IsToken = true;
wserverport.Port = Convert.ToInt32(Port_textBox.Text);
wserverport.PortType = WeavePortTypeEnum.Json;
weaveTCPcloud.StartServer(wserverport);
weaveTCPcloud.WeaveServerUpdateSocketCallBackEvent += OnWeaveUpdateSocket;
weaveTCPcloud.WeaveServerReceiveSocketMessageCallBackEvent += OnWeaveReceiveSocketMessage;
weaveTCPcloud.WeaveServerDeleteSocketCallBackEvent += OnWeaveDeleteSocket;
weaveTCPcloud.WeaveServerGetUnityPlayerOnLineCallBackEvent += OnWeaveServerGetUnityPlayerOnLineEvent;
weaveTCPcloud.WeaveServerGetUnityPlayerOffLineCallBackEvent += OnWeaveServerGetUnityPlayerOffLineEvent;
weaveTCPcloud.WeaveServerReceiveOnLineUnityPlayerMessageCallBackEvent += OnWeaveServerReceiveOnLineUnityPlayerMessageEvent;
StartListen_button.Content = "正在监听";
StartListen_button.IsEnabled = false;
}
private void OnWeaveServerGetUnityPlayerOnLineEvent(UnityPlayerOnClient gamer)
{
//当有用户 账号密码登陆成功的时候
AddListBoxItemAction(loginedUserList, CopyUnityPlayerOnClientToMyListBoxItem(gamer));
SetServerReceiveText("Unity登陆后的玩家--触发了一次(OnWeaveServerUpdateUnityPlayerSetOnLineEvent)" + Environment.NewLine);
}
private void OnWeaveServerGetUnityPlayerOffLineEvent(UnityPlayerOnClient gamer)
{
SetServerReceiveText("Unity玩家下线事件--触发了一次(OnWeaveServerGetUnityPlayerOffLineEvent)" + Environment.NewLine);
}
private void OnWeaveServerReceiveOnLineUnityPlayerMessageEvent(byte command, string data, UnityPlayerOnClient gamer)
{
// 登陆用户发送过来的数据
SetServerReceiveText("Unity玩家登陆事件--触发了一次(OnWeaveServerReceiveOnLineUnityPlayerMessageEvent)" + Environment.NewLine);
WeaveSession ws = Newtonsoft.Json.JsonConvert.DeserializeObject<WeaveSession>( data);
SetServerReceiveText("收到【"+gamer.UserName+"】发来的数据: " + ws.Root + Environment.NewLine );
}
private void OnWeaveUpdateSocket(WeaveOnLine weaveOnLine)
{
SetServerReceiveText("Socket连接--触发了一次(OnWeaveUpdateSocket)" + Environment.NewLine);
//有 Sokcet客户端连接到服务器的时候,暂未 账号,密码认证状态
AddListBoxItemAction(connectedSocketItemList, CopyWeaveOnLineToMyListBoxItem(weaveOnLine) );
}
private void OnWeaveReceiveSocketMessage(byte command, string data, WeaveOnLine _socket)
{
WeaveSession ws = Newtonsoft.Json.JsonConvert.DeserializeObject<WeaveSession>(data);
SetServerReceiveText("Socket发来数据--触发了一次(OnWeaveReceiveSocketMessage)" + Environment.NewLine);
SetServerReceiveText("收到的数据为: " + ws.Root + Environment.NewLine);
}
private void OnWeaveDeleteSocket(WeaveOnLine weaveOnLine)
{
SetServerReceiveText("Socket断开--退出事件--触发了一次(OnWeaveDeleteSocket)" + Environment.NewLine);
RemoveListBoxItemAction(connectedSocketItemList, CopyWeaveOnLineToMyListBoxItem(weaveOnLine));
MyListBoxItem oneItem = loginedUserList.Find(item => item.Ip == weaveOnLine.Socket.RemoteEndPoint.ToString());
RemoveListBoxItemAction(loginedUserList, oneItem );
}
private void StopListen_button_Click(object sender, RoutedEventArgs e)
{
weaveTCPcloud.P2Server = null;
weaveTCPcloud = null;
Application.Current.Shutdown();
Environment.Exit(0);// 可以立即中断程序执行并退出
}
private void SendMsg_button_Click(object sender, RoutedEventArgs e)
{
string serverMsg = InputSendMessage_textBox.Text;
int unityGamecount = weaveTCPcloud.unityPlayerOnClientList.Count;
if (string.IsNullOrEmpty(serverMsg) || weaveTCPcloud.weaveOnline.Count==0)
return;
WeaveOnLine[] _allWeaveOnLine = new WeaveOnLine[weaveTCPcloud.weaveOnline.Count];
weaveTCPcloud.weaveOnline.CopyTo(_allWeaveOnLine);
foreach (WeaveOnLine oneWeaveOnLine in _allWeaveOnLine)
{
weaveTCPcloud.P2Server.Send(oneWeaveOnLine.Socket, 0x01, "服务器主动给所有客户端发消息了: " + serverMsg);
}
// MessageBox.Show("客户端在线数量:"+ _allWeaveOnLine.Length);
}
private void UpdateServerReceiveTb(TextBlock tb, string text)
{
tb.Text += text;
}
private void SetServerReceiveText(string newtext)
{
Action<TextBlock, String> updateAction = new Action<TextBlock, string>(UpdateServerReceiveTb);
ServerReceive_textBlock.Dispatcher.BeginInvoke(updateAction, ServerReceive_textBlock, newtext);
}
public MyListBoxItem CopyUnityPlayerOnClientToMyListBoxItem(UnityPlayerOnClient one)
{
MyListBoxItem item = new MyListBoxItem()
{
UIName_Id = one.Socket.RemoteEndPoint.ToString(),
ShowMsg = "UserIP:" + one.Socket.RemoteEndPoint.ToString() + " -Token:" + one.Token,
UserName = one.UserName,
Ip = one.Socket.RemoteEndPoint.ToString()
};
return item;
}
public MyListBoxItem CopyWeaveOnLineToMyListBoxItem(WeaveOnLine one)
{
MyListBoxItem item = new MyListBoxItem()
{
UIName_Id = one.Socket.RemoteEndPoint.ToString(),
ShowMsg = "UserIP:" + one.Socket.RemoteEndPoint.ToString() + " -Token:" + one.Token,
UserName = "Uname:"+ one.Socket.RemoteEndPoint.ToString(),
Ip = one.Socket.RemoteEndPoint.ToString()
};
return item;
}
public void AddListBoxItem(List<MyListBoxItem> sList , MyListBoxItem one)
{
sList.Add(one);
CheckListBoxSource();
}
public void AddListBoxItemAction(List<MyListBoxItem> sList, MyListBoxItem one)
{
Action< List < MyListBoxItem > , MyListBoxItem> addListBoxItemAction =
new Action<List<MyListBoxItem> , MyListBoxItem>(AddListBoxItem);
this.Dispatcher.BeginInvoke(addListBoxItemAction,sList , one);
}
public void RemoveListBoxItem(List<MyListBoxItem> sList, MyListBoxItem one)
{
MyListBoxItem item = sList.Find(i=>i.Ip == one.Ip);
if(item != null)
{
sList.Remove(item);
}
CheckListBoxSource();
}
public void RemoveListBoxItemAction(List<MyListBoxItem> sList, MyListBoxItem one)
{
Action<List<MyListBoxItem>, MyListBoxItem> removeListBoxItemAction =
new Action<List<MyListBoxItem>, MyListBoxItem>(RemoveListBoxItem);
this.Dispatcher.BeginInvoke(removeListBoxItemAction, sList , one);
}
public void CheckListBoxSource()
{
//数据发生变化后,重新设置登陆后的用户列表Listbox的数据源
LoginedUser_listBox.ItemsSource = null;
LoginedUser_listBox.ItemsSource = loginedUserList;
//数据发生变化后,重新设置连接到服务器的Socket列表的Listbox的数据源
ConnectedSocket_listBox.ItemsSource = null;
ConnectedSocket_listBox.ItemsSource = connectedSocketItemList;
}
protected override void OnClosed(EventArgs e)
{
weaveTCPcloud.P2Server = null;
weaveTCPcloud = null;
//Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
//if (this.IsAfreshLogin == true) return;
Application.Current.Shutdown();
Environment.Exit(0);// 可以立即中断程序执行并退出
base.OnClosed(e);
}
}
public class MyListBoxItem
{
public string UIName_Id { get; set; }
public string Ip { get; set; }
public string ShowMsg { get; set; }
public string UserName { get; set; }
}
}
XMAL代码
<Window x:Class="WeavingSocketServerWPF.MyUnityServer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WeavingSocketServerWPF"
mc:Ignorable="d"
Title="MyUnityServer" Height="631.609" Width="998.81">
<Grid>
<Label x:Name="label" Content="端口号" HorizontalAlignment="Left" Margin="23,10,0,0" VerticalAlignment="Top" Height="38" Width="111" FontSize="16"/>
<TextBox x:Name="Port_textBox" HorizontalAlignment="Left" Height="46" Margin="23,53,0,0" TextWrapping="Wrap" Text="10155" VerticalAlignment="Top" Width="130" FontSize="16"/>
<Button x:Name="StartListen_button" Content="开始监听端口" HorizontalAlignment="Left" Margin="179,53,0,0" VerticalAlignment="Top" Width="115" Height="41" FontSize="18" Click="StartListen_button_Click"/>
<ListBox x:Name="ConnectedSocket_listBox" HorizontalAlignment="Left" Height="309" Margin="467,53,0,0" VerticalAlignment="Top" Width="519">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Path=ShowMsg}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label x:Name="UserList_label" Content="连接到服务的Socket列表" HorizontalAlignment="Left" Margin="467,10,0,0" VerticalAlignment="Top" Height="38" Width="194" FontSize="16"/>
<Label x:Name="label_Copy" Content="收到的信息" HorizontalAlignment="Left" Margin="23,348,0,0" VerticalAlignment="Top" Height="32" Width="111" FontSize="16"/>
<Label x:Name="label_Copy1" Content="要发送的消息" HorizontalAlignment="Left" Margin="23,131,0,0" VerticalAlignment="Top" Height="38" Width="111" FontSize="16"/>
<TextBox x:Name="InputSendMessage_textBox" HorizontalAlignment="Left" Height="46" Margin="23,174,0,0" TextWrapping="Wrap" Text="Message" VerticalAlignment="Top" Width="217" FontSize="16"/>
<Button x:Name="SendMsg_button" Content="发送消息" HorizontalAlignment="Left" Margin="23,247,0,0" VerticalAlignment="Top" Width="217" Height="82" FontSize="18" Click="SendMsg_button_Click"/>
<Button x:Name="StopListen_button" Content="关闭服务器" HorizontalAlignment="Left" Margin="322,53,0,0" VerticalAlignment="Top" Width="124" Height="41" FontSize="18" Click="StopListen_button_Click"/>
<ListBox x:Name="LoginedUser_listBox" HorizontalAlignment="Left" Height="212" Margin="300,150,0,0" VerticalAlignment="Top" Width="146">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Path=UserName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label x:Name="UserList_label_Copy" Content="已登陆玩家" HorizontalAlignment="Left" Margin="300,107,0,0" VerticalAlignment="Top" Height="38" Width="146" FontSize="16" BorderBrush="#FFFB0808" OpacityMask="Red" Foreground="Red"/>
<ScrollViewer HorizontalAlignment="Left" Height="190" Margin="23,380,0,0" VerticalAlignment="Top" Width="958">
<ScrollViewer.Content>
<TextBlock x:Name="ServerReceive_textBlock" HorizontalAlignment="Left" Margin="0,0,0,0" TextWrapping="Wrap" Text="MSG" VerticalAlignment="Top" Width="963" Foreground="#FFFF1207" Background="#FFD3CDCD" FontSize="14"/>
</ScrollViewer.Content>
</ScrollViewer>
</Grid>
</Window>
界面图
WeaveSocket官方QQ群17375149
项目地址:https://gitee.com/dreamsfly900/universal-Data-Communication-System-for-windows/tree/master/Example
本节到此结束,未完待续