Created
February 21, 2014 14:29
-
-
Save yakreved/9135251 to your computer and use it in GitHub Desktop.
SocketMessagesDispatcher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Threading; | |
using System; | |
// В этот класс преобразуется JSON сообщения от сервера | |
public struct SocketMessage { | |
// Первый элемент массива - заголовок сообщения | |
// ["kill_combat", 1] | |
// name == "kill_combat" | |
public string name; | |
// Параметр сообщения, может быть разного типа, или null, если нет параметра | |
// ["wait", {"delay": 30} | |
// parametr == Dictionary { delay = 30 } | |
public object parameter; | |
// Мы подразумеваем что в сообщение максимум один параметр (имя + параметр) | |
public override string ToString() | |
{ | |
return "[\""+name+"\","+JsonFx.Json.JsonWriter.Serialize(parameter)+"]"; | |
} | |
} | |
// Данный клас принимает сообщения из сокета. Склеивает или расклеивает их на отдельные JSON-ки | |
// И запускает заданный контроллер для каждого типа сообщения | |
// Например можно задать такой роут: | |
// SocketMessageDispatcher.addRoute("login_successfull", delegate(param) { new LoginController().success() }) | |
// Это значит, что когда придёт сообщение от сервера типа: | |
// ["login_successfull", "ok"] | |
// вызовется метод success контроллера LoginController | |
// | |
// У класса есть два статических метода main и combat, предназначенные соответвенно | |
// для обработки сообщений с мейн-сервера и комбат сервера | |
// | |
// Из-за огранчений юнити по работе с главным тредом, вместе с этим классом работает | |
public class SocketMessagesDispatcher { | |
private static SocketMessagesDispatcher _main; | |
private static SocketMessagesDispatcher _combat; | |
private string msgBuffer = String.Empty; | |
public delegate void RouteDelegate(object param); | |
private Dictionary<string, RouteDelegate> RouteDict = new Dictionary<string, RouteDelegate>(); | |
// Инстанс для соединения с главным сервером приложения | |
public static SocketMessagesDispatcher main { | |
get { | |
if(_main == null) { | |
_main = new SocketMessagesDispatcher(); | |
} | |
return _main; | |
} | |
} | |
// Инстанс для соединения с сервером боя | |
public static SocketMessagesDispatcher combat { | |
get { | |
if(_combat == null) { | |
_combat = new SocketMessagesDispatcher(); | |
} | |
return _combat; | |
} | |
} | |
// Получаем сообщение от сервера, оно может быть не валидным JSON-ом, например частью сообщения, или сразу двумя сообщениями | |
public void receivedRawMessage(string msg) { | |
Dbg.Log(msg); | |
lock(this) { | |
Dbg.Log("Raw message receiver" + msg); | |
msg = msg.Replace("\0", ""); | |
string completeMsg = msgBuffer + msg; | |
if(completeMsg[completeMsg.Length - 1] == '\n') { | |
msgBuffer = ""; | |
} | |
else { | |
msgBuffer += msg; | |
return; | |
} | |
foreach(string queryString in completeMsg.Split('\n')) { | |
SocketMessage message = new SocketMessage(); | |
try { | |
if(queryString == "") continue; | |
message = JsonParser.ParseJsonToSocketMessage(queryString); | |
} | |
catch(Exception ex){ | |
Dbg.Log("Can't parse json message <<<" + queryString + ">>> " + ex); | |
continue; | |
} | |
SocketMessagesQueue.AddMessage(message, this); | |
} | |
} | |
} | |
// Добавляем обработчик сообещений. Можно в одну строку типа: | |
// SocketMessagesDispatcher.addRoute('some', delegate(p) { ... }).addRoute('another', delegate(p) { ... }) | |
public SocketMessagesDispatcher addRoute(string messageName, RouteDelegate route){ | |
RouteDict[messageName] = route; | |
return this; | |
} | |
public void Route(SocketMessage message) { | |
if(RouteDict.ContainsKey(message.name)) { | |
Dbg.Log("Run routing on " + message.name); | |
RouteDict[message.name](message); | |
} | |
else { | |
Dbg.Log("Can't route server message " + message.name); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment