功能:
客户端1,2都连接了服务器;
客户端1给服务器发了消息“asdasd”
服务器做Event事件发给所有客户端
客户端1,2全都收到了消息“asdasd”
注意点:MyGameServer里面,一个peer就是一个连接,所以我们每次有一个客户端连接,就要把其peer添加到一个list中。服务器然后在发送Event的时候,遍历List,群发就ok。
———————————————————————————————————————————
服务端
ChatHandler.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common;
using Photon.SocketServer;
namespace RRGameServer.Handler
{
class ChatHandler : BaseHandler
{
public ChatHandler()
{
OpCode = Common.OperationCode.Chat;
}
public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer)
{
string hello = DicTool.GetValue(operationRequest.Parameters, (byte)ParaCode.Chat) as string;
MyGameServer.log.Info("收到客户端发来的聊天内容:" + hello);
//返回:已经收到消息
OperationResponse response = new OperationResponse(operationRequest.OperationCode);
response.ReturnCode = (short)Common.ReturnCode.Success;
peer.SendOperationResponse(response, sendParameters);
//发送给其他的客户端 OnEvent
//发给自己
//推送一个Event
EventData ed = new EventData((byte)OperationCode.Chat);//操作码
var data2 = new Dictionary();
data2.Add((byte)ParaCode.Chat, hello);//参数码
ed.Parameters = data2;
//peer.SendEvent(ed, new SendParameters());
foreach (var peerItem in MyGameServer.Instance.PeerList)
{
peerItem.SendEvent(ed, new SendParameters());
}
}
}
}
MyGameServer.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common;
using ExitGames.Logging;
using ExitGames.Logging.Log4Net;
using log4net.Config;
using Photon.SocketServer;
using RRGameServer.Handler;
using RRGameServer.Manager;
namespace RRGameServer
{
//所有的Server,都要继承ApplicationBase,然后实现ApplicationBase的三个方法
public class MyGameServer : ApplicationBase
{
public static MyGameServer Instance;
public static readonly ILogger log = LogManager.GetCurrentClassLogger();
public List PeerList = new List();//用户保存所有的peer,一个客户端连接就会有一个peer
//当有一个客户端连接上以后,就会执行此方法
protected override PeerBase CreatePeer(InitRequest initRequest)
{
log.Info("一个客户端连接");
var p = new ClientPeer(initRequest);
PeerList.Add(p);
return p;
}
//服务器初始化函数
protected override void Setup()
{
Instance = this;
log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(
Path.Combine(this.ApplicationRootPath, "bin_Win64"), "log");
FileInfo configFileInfo = new FileInfo(Path.Combine(this.BinaryPath, "log4net.config"));
if (configFileInfo.Exists)
{
LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);//photon知道日志输出
XmlConfigurator.ConfigureAndWatch(configFileInfo);//读取配置
}
log.Info("服务器启动啦");
//log.Info(UserManager.Instance.GetUserById(7).Username);
InitHandler();//初始化
}
//服务器关闭函数
protected override void TearDown()
{
log.Info("服务器关闭啦");
}
public Dictionary HandlerDic = new Dictionary();
public void InitHandler()
{
//一开始就全部初始化
LoginHandler LH = new LoginHandler();
//log.Info("初始化操作码:" + LH.OpCode);
HandlerDic.Add(LH.OpCode, LH);
SignHandler handler = new SignHandler();
HandlerDic.Add(handler.OpCode, handler);
ChatHandler chathandler = new ChatHandler();
HandlerDic.Add(chathandler.OpCode, chathandler);
}
}
}
———————————————————————————————————————————
客户端
ChatRequest.cs:
using System.Collections;
using System.Collections.Generic;
using Common;
using ExitGames.Client.Photon;
using UnityEngine;
using UnityEngine.UI;
public class ChatRequest : Request
{
public InputField input;
[HideInInspector]
public string Hello;
public override void DefaultRequest()
{
//构造参数
var data = new Dictionary();
//构造参数
data.Add((byte)ParaCode.Chat, Hello);
//发送
PhotonEngine.peer.OpCustom((byte)OpCode, data, true);
}
public override void OnOprationRespionse(OperationResponse operationResponse)
{
if (operationResponse.ReturnCode == (byte)ReturnCode.Success)
{
Debug.Log("发送成功");
}
else
{
Debug.Log("发送失败");
}
}
public void OnChatBtn()
{
Hello = input.text;
DefaultRequest();
}
}
PhotonEngine.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ExitGames.Client.Photon;
using Common;
public class PhotonEngine : MonoBehaviour,IPhotonPeerListener {
public static PhotonEngine Instance;
//用字典来缓存每次的请求和码
//这里就能体现出来我们Request抽象类的好处了,不然每次这边都是不同的类型,使用抽象类就统一了
private Dictionary RequestDic = new Dictionary();
public static PhotonPeer peer;
private void Awake()
{
if (Instance == null)
{
Instance = this;
//当前Gameobject不会随场景的销毁而销毁
DontDestroyOnLoad(this.gameObject);
}
}
void Start () {
peer = new PhotonPeer(this,ConnectionProtocol.Udp);
peer.Connect("127.0.0.1:5055", "MyGame6");//通过ip连接到到对应的我们config中配置的Allpication
}
void Update () {
peer.Service();//开启服务
}
private void OnDestroy()//销毁的时候
{
if(peer!=null&&peer.PeerState == PeerStateValue.Connected)//如果存在且保持连接状态
{
peer.Disconnect();//就断开连接
}
}
public void DebugReturn(DebugLevel level, string message)
{
}
public void OnEvent(EventData eventData)
{
if ((byte)OperationCode.Chat == eventData.Code)
{
var data = eventData.Parameters;
object intValue;
data.TryGetValue((byte)ParaCode.Chat, out intValue);
Debug.Log("收到服务器:"+intValue);
}
return;
switch (eventData.Code)
{
//case 1:
// //解析数据
// var data = eventData.Parameters;
// object intValue, StringValue;
// data.TryGetValue(1, out intValue);
// data.TryGetValue(2, out StringValue);
// Debug.Log("收到服务器的响应Event推送,OpCode:1" + intValue.ToString() + ":" + StringValue.ToString());
// break;
default:
break;
}
}
public void OnOperationResponse(OperationResponse operationResponse)
{
Request request = null;
//此处就是工具类
DicTool.GetValue(RequestDic, (OperationCode)operationResponse.OperationCode)
.OnOprationRespionse(operationResponse);
//下面注释的代码可以用上方工具类代替
//bool b =RequestDic.TryGetValue((OperationCode)operationResponse.OperationCode, out request);
//if (b)
//{
// request.OnOprationRespionse(operationResponse);
//}
//else
//{
// Debug.LogError("未找到对应code的请求request");
//}
return;
//switch (operationResponse.OperationCode)
//{
// case 1:
// Debug.Log("收到服务器的响应,OpCode:1");
// //解析数据
// var data = operationResponse.Parameters;
// object intValue;
// data.TryGetValue(1, out intValue);
// object StringValue;
// data.TryGetValue(2, out StringValue);
// Debug.Log("收到客户端的请求,OpCode:1" + intValue.ToString() + ":" + StringValue.ToString());
// break;
// default:
// break;
// }
}
public void OnStatusChanged(StatusCode statusCode)
{
Debug.LogError(statusCode);
}
//private Dictionary RequestDic = new Dictionary();
public void AddRequest(Request r)
{
RequestDic.Add(r.OpCode, r);
}
public void RemoveRequest(Request r)
{
RequestDic.Remove(r.OpCode);
}
}