├── README.md
├── pomelo-unityclient.sln
├── pomelo-unityclient.userprefs
└── pomelo-unityclient
├── bin
└── Debug
│ ├── SimpleJson.dll
│ ├── SocketIO.dll
│ ├── SuperSocket.ClientEngine.Common.dll
│ ├── SuperSocket.ClientEngine.Core.dll
│ ├── SuperSocket.ClientEngine.Protocol.dll
│ ├── SuperSocket.ClientEngine.Proxy.dll
│ ├── WebSocket4Net.dll
│ ├── pomelo-unityclient.dll
│ └── pomelo-unityclient.pdb
├── pomelo-unityclient.csproj
├── pomelo-unityclient.pidb
└── pomelo-unityclient
├── EventManager.cs
├── PomeloClient.cs
└── Protocol.cs
/README.md:
--------------------------------------------------------------------------------
1 | pomelo-unityclient
2 | =============================
3 | This is the pomelo client for unity3d. The project is based on some libraries as follows:
4 |
5 | * WebSocket4Net (http://websocket4net.codeplex.com/), and you should choose the .Net 3.5 runtime version.
6 |
7 | * UnitySocketIO (https://github.com/NetEase/UnitySocketIO).
8 |
9 | ## How to use
10 | It is very simple to use pomelo-unityclient. Copy all the DLLS locating in the file of /bin/Debug/
11 | to your project.
12 |
13 | Of course, you can download this project and compile it:
14 |
15 | >git clone https://github.com/NetEase/pomelo-unityclient.git
16 |
17 | ## API
18 |
19 | Create and initialize a new pomelo client.
20 |
21 | ```c#
22 | PomeloClient pclient = new PomeloClient(url);
23 | pclient.init();
24 |
25 | ```
26 |
27 | Send request to server and process data in callback.
28 |
29 | ```c#
30 | pclient.request(route, message, (data)=>{
31 | //process the data
32 | });
33 | ```
34 | Notify server without response
35 |
36 | ```c#
37 | pclient.notify(route, messge);
38 | ```
39 | Add event listener, process broadcast message
40 | ```c#
41 | pclient.On(route, (data)=>{
42 | //process the data
43 | });
44 | ```
45 | Disconnect the client.
46 | ```c#
47 | pclient.disconnect();
48 | ```
49 | ##License
50 | (The MIT License)
51 |
52 | Copyright (c) 2012-2013 NetEase, Inc. and other contributors
53 |
54 | Permission is hereby granted, free of charge, to any person obtaining a
55 | copy of this software and associated documentation files (the 'Software'),
56 | to deal in the Software without restriction, including without limitation
57 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
58 | and/or sell copies of the Software, and to permit persons to whom the
59 | Software is furnished to do so, subject to the following conditions:
60 |
61 | The above copyright notice and this permission notice shall be included in
62 | all copies or substantial portions of the Software.
63 |
64 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
65 |
--------------------------------------------------------------------------------
/pomelo-unityclient.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual Studio 2008
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pomelo-unityclient", "pomelo-unityclient\pomelo-unityclient.csproj", "{E31589A2-F031-42F7-B809-FED22BB6EC30}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|x86 = Debug|x86
9 | Release|x86 = Release|x86
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {E31589A2-F031-42F7-B809-FED22BB6EC30}.Debug|x86.ActiveCfg = Debug|x86
13 | {E31589A2-F031-42F7-B809-FED22BB6EC30}.Debug|x86.Build.0 = Debug|x86
14 | {E31589A2-F031-42F7-B809-FED22BB6EC30}.Release|x86.ActiveCfg = Release|x86
15 | {E31589A2-F031-42F7-B809-FED22BB6EC30}.Release|x86.Build.0 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(MonoDevelopProperties) = preSolution
18 | StartupItem = pomelo-unityclient\pomelo-unityclient.csproj
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/pomelo-unityclient.userprefs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/SimpleJson.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/SimpleJson.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/SocketIO.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/SocketIO.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Common.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Common.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Core.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Protocol.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Protocol.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Proxy.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/SuperSocket.ClientEngine.Proxy.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/WebSocket4Net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/WebSocket4Net.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/pomelo-unityclient.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/pomelo-unityclient.dll
--------------------------------------------------------------------------------
/pomelo-unityclient/bin/Debug/pomelo-unityclient.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/bin/Debug/pomelo-unityclient.pdb
--------------------------------------------------------------------------------
/pomelo-unityclient/pomelo-unityclient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 9.0.21022
7 | 2.0
8 | {E31589A2-F031-42F7-B809-FED22BB6EC30}
9 | Library
10 | pomelounityclient
11 | pomelo-unityclient
12 | v3.5
13 |
14 |
15 | true
16 | full
17 | false
18 | bin\Debug
19 | DEBUG;
20 | prompt
21 | 4
22 | x86
23 | false
24 |
25 |
26 | none
27 | false
28 | bin\Release
29 | prompt
30 | 4
31 | x86
32 | false
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | ..\..\..\Chat\Assets\Plugins\SimpleJson.dll
43 |
44 |
45 | ..\..\..\Chat\Assets\Plugins\SocketIO.dll
46 |
47 |
48 | ..\..\..\Chat\Assets\Plugins\SuperSocket.ClientEngine.Common.dll
49 |
50 |
51 | ..\..\..\Chat\Assets\Plugins\SuperSocket.ClientEngine.Core.dll
52 |
53 |
54 | ..\..\..\Chat\Assets\Plugins\SuperSocket.ClientEngine.Protocol.dll
55 |
56 |
57 | ..\..\..\Chat\Assets\Plugins\SuperSocket.ClientEngine.Proxy.dll
58 |
59 |
60 | ..\..\..\Chat\Assets\Plugins\WebSocket4Net.dll
61 |
62 |
63 |
--------------------------------------------------------------------------------
/pomelo-unityclient/pomelo-unityclient.pidb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetEase/pomelo-unityclient/f276c3edacde8a8d8f320a245e3c212ecfdb3bbe/pomelo-unityclient/pomelo-unityclient.pidb
--------------------------------------------------------------------------------
/pomelo-unityclient/pomelo-unityclient/EventManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Text;
7 | using SocketIOClient.Messages;
8 | using SimpleJson;
9 |
10 | namespace pomeloUnityClient
11 | {
12 | public class EventManager : IDisposable
13 | {
14 |
15 | private Dictionary> callBackMap;
16 | private Dictionary>> eventMap;
17 |
18 | public EventManager()
19 | {
20 | this.callBackMap = new Dictionary>();
21 | this.eventMap = new Dictionary>>();
22 | }
23 |
24 | //Adds callback to callBackMap by id.
25 | public void AddCallBack(int id, Action callback)
26 | {
27 | if (id != null && callback != null) {
28 | this.callBackMap.Add(id, callback);
29 | }
30 | }
31 |
32 | ///
33 | /// Invoke the callback when the server return messge .
34 | ///
35 | ///
36 | /// Pomelo message.
37 | ///
38 | public void InvokeCallBack(JsonObject msg)
39 | {
40 | if (msg != null) {
41 | Action action = null;
42 | object id = null;
43 | object body = null;
44 | if (msg.TryGetValue("id", out id)){
45 | if(this.callBackMap.TryGetValue(Convert.ToInt32(id), out action)) {
46 | if (msg.TryGetValue("body", out body)) {
47 | action.Invoke((JsonObject)SimpleJson.SimpleJson.DeserializeObject(body.ToString()));
48 | }
49 | }
50 | }
51 | }
52 | }
53 |
54 | //Adds the event to eventMap by name.
55 | public void AddOnEvent(string eventName, Action callback)
56 | {
57 | List> list = null;
58 | if (this.eventMap.TryGetValue(eventName, out list)) {
59 | list.Add(callback);
60 | } else {
61 | list = new List>();
62 | list.Add(callback);
63 | this.eventMap.Add(eventName, list);
64 | }
65 | }
66 |
67 | ///
68 | /// If the event exists,invoke the event when server return messge.
69 | ///
70 | ///
71 | ///
72 | ///
73 | ///
74 | public void InvokeOnEvent (JsonObject msg) {
75 | List> list = null;
76 | object route = null;
77 | if (msg.TryGetValue("route", out route)) {
78 | if (this.eventMap.TryGetValue(route.ToString(), out list)) {
79 | int length = list.Count;
80 | for(int i = 0; i < length; i++) {
81 | Action ap = list[i];
82 | ap.Invoke(msg);
83 | }
84 | }
85 | }
86 | }
87 |
88 |
89 | // Dispose() calls Dispose(true)
90 | public void Dispose()
91 | {
92 | Dispose(true);
93 | GC.SuppressFinalize(this);
94 | }
95 |
96 | // The bulk of the clean-up code is implemented in Dispose(bool)
97 | protected void Dispose(bool disposing)
98 | {
99 | this.callBackMap.Clear();
100 | this.eventMap.Clear();
101 | }
102 | }
103 | }
104 |
105 |
--------------------------------------------------------------------------------
/pomelo-unityclient/pomelo-unityclient/PomeloClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Diagnostics;
4 | using SimpleJson;
5 | using System.Collections.Generic;
6 | using SocketIOClient;
7 |
8 | namespace pomeloUnityClient
9 | {
10 | public class PomeloClient
11 | {
12 | private Client socket = null;
13 | private int reqId = 0;
14 | private const string ARRAY_FLAG = "[";
15 | private const string URL_HEADER = "http://";
16 | private EventManager eventManager = null;
17 |
18 | public PomeloClient (string url)
19 | {
20 | string checkedUrl = this.checkUrl(url);
21 |
22 | try{
23 | this.socket = new Client(checkedUrl);
24 | } catch (Exception e) {
25 | Console.WriteLine(string.Format("Error in new SocketIO:{0}", e.Message));
26 | }
27 |
28 | this.eventManager = new EventManager();
29 | }
30 |
31 | //Init socket and make connection.
32 | public void init(){
33 |
34 | this.socket.Opened += this.SocketOpened;
35 | this.socket.Message += this.SocketMessage;
36 | this.socket.SocketConnectionClosed += this.SocketConnectionClosed;
37 | this.socket.Error += this.SocketError;
38 |
39 | this.socket.Connect();
40 | }
41 |
42 | //Check out the url and complemented it.
43 | private string checkUrl(string url){
44 | string trueUrl;
45 |
46 | if (!url.Contains(URL_HEADER)) {
47 | trueUrl = URL_HEADER + url;
48 | } else {
49 | trueUrl = url;
50 | }
51 |
52 | return trueUrl;
53 | }
54 |
55 | //Close the socket and free the resources.
56 | public void disconnect(){
57 | this.socket.Close();
58 | if (this.eventManager != null) {
59 | this.eventManager.Dispose();
60 | this.eventManager = null;
61 | }
62 | this.closeSocketIO();
63 |
64 | }
65 |
66 | ///
67 | /// Sends the message to server.
68 | ///
69 | ///
70 | /// Req identifier.
71 | ///
72 | ///
73 | /// Route.
74 | ///
75 | ///
76 | /// Message.
77 | ///
78 | private void sendMessage(int reqId, string route, JsonObject msg){
79 | string message = "";
80 | try{
81 | message = Protocol.encode(reqId, route, msg);
82 | }catch(ArgumentException e) {
83 | Console.WriteLine(string.Format("Error in protocol.encode:{0}", e.Message));
84 | }
85 |
86 | this.socket.Send(message);
87 | }
88 |
89 | ///
90 | /// Request message from server and register callback.
91 | ///
92 | ///
93 | /// Route.
94 | ///
95 | ///
96 | /// Message.
97 | ///
98 | ///
99 | /// Action.
100 | ///
101 | public void request(string route, JsonObject msg, Action action){
102 |
103 | JsonObject returnMSg = filter(msg);
104 | reqId++;
105 | this.eventManager.AddCallBack(reqId, action);
106 | this.sendMessage(reqId, route, returnMSg);
107 |
108 | }
109 |
110 | //Notify message to server.
111 | public void notify(string route, JsonObject msg) {
112 | this.sendMessage(0, route, msg);
113 | }
114 |
115 | //Listen evetn named eventName.
116 | public void On(string eventName, Action action){
117 | this.eventManager.AddOnEvent(eventName, action);
118 | }
119 |
120 | //Add msg time.
121 | private JsonObject filter(JsonObject msg) {
122 | if (msg == null) {
123 | msg = new JsonObject();
124 | }
125 | var st= new DateTime(1970,1,1);
126 | TimeSpan t= (DateTime.Now.ToUniversalTime()-st);
127 | Int64 retval= (Int64)(t.TotalMilliseconds+0.5);
128 | msg.Add("timestamp", retval);
129 | return msg;
130 | }
131 |
132 | ///
133 | /// Processes the message and invoke callback or event.
134 | ///
135 | ///
136 | /// Message.
137 | ///
138 | private void processMessage(string msg){
139 | JsonObject jsonMsg = (JsonObject)SimpleJson.SimpleJson.DeserializeObject(msg);
140 | Object id = null;
141 | //-----------the request and notify message from server-----------------
142 | if (jsonMsg.TryGetValue("id", out id)) {
143 | this.eventManager.InvokeCallBack(jsonMsg);
144 | //------------bordcast message form server------------------------------
145 | } else {
146 | this.eventManager.InvokeOnEvent(jsonMsg);
147 | }
148 | }
149 |
150 | //Processes the message and invoke callback or event.
151 | private void processMessageBatch(string msgs){
152 | JsonArray jsonArray = (JsonArray) SimpleJson.SimpleJson.DeserializeObject(msgs);
153 | int length = jsonArray.Count;
154 | for (int i = 0; i < length; i++) {
155 | this.processMessage(jsonArray[i].ToString());
156 | }
157 | }
158 |
159 | //Free the resources
160 | private void closeSocketIO(){
161 | if (this.socket != null) {
162 | this.socket.Opened -= this.SocketOpened;
163 | this.socket.Message -= this.SocketMessage;
164 | this.socket.SocketConnectionClosed -= this.SocketConnectionClosed;
165 | this.socket.Error -= this.SocketError;
166 |
167 | this.socket = null;
168 | }
169 | }
170 |
171 | //connection opened event.
172 | private void SocketOpened (object sender, EventArgs e){
173 | Console.WriteLine("The socketIO opend!");
174 | }
175 | ///
176 | /// When message from server comes, it invoke.
177 | ///
178 | ///
179 | /// Sender.
180 | ///
181 | ///
182 | /// E.
183 | ///
184 | private void SocketMessage (object sender, MessageEventArgs e) {
185 |
186 | if ( e!= null && e.Message.Event == "message") {
187 | string msg = e.Message.MessageText;
188 | if (msg.IndexOf(ARRAY_FLAG) == 0) {
189 | this.processMessageBatch(msg);
190 | } else {
191 | this.processMessage(msg);
192 | }
193 | }
194 | }
195 |
196 | //Connetction close event.
197 | private void SocketConnectionClosed (object sender, EventArgs e) {
198 | Console.WriteLine("WebSocketConnection was terminated!");
199 | }
200 |
201 | //Connection error event.
202 | private void SocketError (object sender, ErrorEventArgs e) {
203 | Console.WriteLine("socket client error:");
204 | Console.WriteLine(e.Message);
205 | }
206 | }
207 | }
208 |
209 |
--------------------------------------------------------------------------------
/pomelo-unityclient/pomelo-unityclient/Protocol.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using SimpleJson;
4 | using System.Diagnostics;
5 |
6 | namespace pomeloUnityClient
7 | {
8 | public class Protocol
9 | {
10 | private const int HEADER = 5;
11 |
12 | public Protocol ()
13 | {
14 |
15 | }
16 | ///
17 | /// Encode the messge with id, route and jsonObject.
18 | ///
19 | ///
20 | /// Identifier.
21 | ///
22 | ///
23 | /// Route.
24 | ///
25 | ///
26 | /// Json object.
27 | ///
28 | ///
29 | /// Is thrown when the argument exception.
30 | ///
31 | public static string encode(int id, string route, JsonObject jsonObject){
32 |
33 | if (route.Length > 255) {
34 | throw new System.ArgumentException("route maxlength is overflow");
35 | }
36 |
37 | byte[] byteArray = new byte[HEADER + route.Length];
38 | int index = 0;
39 | byteArray[index++] = Convert.ToByte((id >> 24) & 0xFF);
40 | byteArray[index++] = Convert.ToByte((id >> 16) & 0xFF);
41 | byteArray[index++] = Convert.ToByte((id >> 8) & 0xFF);
42 | byteArray[index++] = Convert.ToByte(id & 0xFF);
43 | byteArray[index++] = Convert.ToByte(route.Length & 0xFF);
44 |
45 | char[] routeArray = route.ToCharArray();
46 | int routeLength = routeArray.Length;
47 | for(int i = 0; i < routeLength; i++) {
48 | byteArray[index++] = Convert.ToByte(routeArray[i]);
49 | }
50 | string encodeString = "";
51 | try{
52 | encodeString = Encoding.UTF8.GetString(byteArray);
53 | }catch(Exception e){
54 | Console.WriteLine(string.Format("Error in new Encoding.UTF8.GetString:{0}", e.Message));
55 | }
56 | return encodeString + jsonObject.ToString();
57 | }
58 |
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------