Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2f373a5

Browse files
committed
Issue menacher#37 added a javascript websocket client for jetserver
1 parent 4b679bd commit 2f373a5

File tree

3 files changed

+285
-0
lines changed

3 files changed

+285
-0
lines changed

jetclient-js/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
This is a javascript client project for [jetserver](https://github.com/menacher/java-game-server/tree/master/jetserver) library. An example html which can connecct to a locally running Jetserver is located at src/test/jetclient.html .
2+
3+
About the Client
4+
================
5+
Click on `start war` button after loading jetclient.html in a websocket enabled browser to start the game. Assumption is that JetServer is running and jetclient.html is using accurate hostname and port number.
6+
7+
Usage as your own game client
8+
=============================
9+
The general usage steps could be as outlined below.
10+
1. Create a config object containing the username, password and connectionkey to connect to game room. If you are using a different protocol, then add the appropriate codec chains also to the config object. By default JSon encoding/decoding is used.
11+
2. Create a session using the session factory by passing in a url for the remote jetserver, config object and a callback function which will receive the session object after successful login to remote jeteserver.
12+
3. Create as many sessions as required using this factory. Generally only one is required for a client. In the example 50 sessions are created.
13+
4. Add necessary handlers to the session using `addHandler` function. The default events generated are provided the jet.Events class. At the very least you would want to add a handler for the jet.Events.SESSION_MESSAGE event to receive incoming events from jetserver.
14+
5. Data can be send to remote server using `session.send` function.
15+
16+
Happy Coding!!
17+

jetclient-js/src/jet-0.1.js

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
(function (jet) {
2+
"use strict";
3+
4+
var evts = new Uint8Array(128);
5+
// do initialization
6+
for (var i = 0; i < evts.length; i++) {
7+
evts[i] = i;
8+
}
9+
10+
// Event code Constants
11+
jet.ANY = evts[0];
12+
jet.PROTOCOL_VERSION = evts[1];
13+
14+
jet.CONNECT = evts[2];
15+
jet.CONNECT_FAILED = evts[6];
16+
jet.LOG_IN = evts[8];
17+
jet.LOG_OUT = evts[10];
18+
jet.LOG_IN_SUCCESS = evts[11];
19+
jet.LOG_IN_FAILURE = evts[12];
20+
jet.LOG_OUT_SUCCESS = evts[14];
21+
jet.LOG_OUT_FAILURE = evts[15];
22+
23+
jet.GAME_LIST = evts[16];
24+
jet.ROOM_LIST = evts[18];
25+
jet.GAME_ROOM_JOIN = evts[20];
26+
jet.GAME_ROOM_LEAVE = evts[22];
27+
jet.GAME_ROOM_JOIN_SUCCESS = evts[24];
28+
jet.GAME_ROOM_JOIN_FAILURE = evts[25];
29+
30+
jet.START = evts[26];
31+
jet.STOP = evts[27];
32+
jet.SESSION_MESSAGE = evts[28];
33+
jet.NETWORK_MESSAGE = evts[29];
34+
jet.CHANGE_ATTRIBUTE = evts[32];
35+
jet.DISCONNECT = evts[34];// Use this one for handling close event of ws.
36+
jet.EXCEPTION = evts[36];
37+
38+
// Functions
39+
// Creates a new event object
40+
jet.nevent = function (eventType, payload, date){
41+
return {
42+
type : eventType,
43+
source : payload,
44+
timeStamp : (typeof date === 'undefined') ? new Date().getTime() : date.getTime()
45+
};
46+
};
47+
48+
// Creates a login event object to login to remote jetserver
49+
jet.LoginEvent = function (config){
50+
return jet.nevent(jet.LOG_IN,[config.user,config.pass,config.connectionKey]);
51+
};
52+
53+
// If using a differnt protocol, then use this codec chain, to decode and encode incoming and outgoing requests. Something like a Chain of Responsibility pattern.
54+
jet.CodecChain = function (){
55+
var me = this;
56+
me.chain = [];
57+
for(var i = 0; i < arguments.length; i++) {
58+
me.chain.push(arguments[i]);
59+
}
60+
61+
me.add = function (func){
62+
me.chain.push(func);
63+
};
64+
65+
me.remove = function (func){
66+
var index = me.chain.indexOf(func);
67+
while(index != -1){
68+
me.chain.splice(index,1);
69+
index = me.chain.indexOf(func);
70+
}
71+
};
72+
73+
me.tranform = function transform(message){
74+
for(var i = 0; i < me.chain.length(); i++){
75+
message = me.chain[i].transform(message);
76+
}
77+
return message;
78+
};
79+
};
80+
81+
// Default codes which use JSON to decode and encode messages.
82+
jet.Codecs = {
83+
encoder : {transform: function (e){ return JSON.stringify(e)}},
84+
decoder : {transform: function (e){
85+
var evt = JSON.parse(e);
86+
if(evt.type != 'undefined' && evt.type == jet.NETWORK_MESSAGE){
87+
evt.type = jet.SESSION_MESSAGE;
88+
}
89+
return evt;
90+
}
91+
}
92+
};
93+
94+
// Generally a client needs only one session to the server. But this function can be used to create more.
95+
jet.sessionFactory = function (url,config,callback){
96+
new Session(url,config,callback);
97+
};
98+
99+
// Used to create a session. Once START event is received from the remote jetserver then the callback is invoked with the created session.
100+
function Session(url, config, callback){
101+
var me = this;
102+
var callbacks = {};
103+
me.inCodecChain = (typeof config.inCodecChain === 'undefined') ? jet.Codecs.decoder : config.inCodecChain;
104+
me.outCodecChain = (typeof config.outCodecChain === 'undefined') ? jet.Codecs.encoder : config.outCodecChain;
105+
var message = getLogin(config);
106+
var ws = new WebSocket(url);
107+
var state = 0;// 0=CONNECTING, 1=CONNECTED,2=CLOSED
108+
109+
ws.onopen = function(){
110+
ws.send(message);
111+
};
112+
113+
// Login to jetserver when the start event is received the callback will return the session.
114+
ws.onmessage = function (e){
115+
var loginDecoder = (typeof config.loginDecoder === 'undefined') ? jet.Codecs.decoder : config.loginDecoder;
116+
var evt = loginDecoder.transform(e.data);
117+
if(!evt.type){
118+
throw new Error("Event object missing 'type' property.");
119+
}
120+
if(evt.type == jet.LOG_IN_FAILURE || evt.type == jet.GAME_ROOM_JOIN_FAILURE){
121+
ws.close();
122+
}
123+
if(evt.type == jet.START){
124+
if (callback && typeof(callback) === 'function') {
125+
state = 1;
126+
applyProtocol(config);
127+
callback(me);
128+
}
129+
}
130+
};
131+
132+
ws.onclose = function (e){
133+
state = 2;
134+
dispatch(jet.DISCONNECT,e);
135+
};
136+
137+
me.addHandler = function(eventName, callback){
138+
callbacks[eventName] = callbacks[eventName] || [];
139+
callbacks[eventName].push(callback);
140+
return me;// chainable
141+
};
142+
143+
me.send = function(aEvt){
144+
if(state != 1){
145+
throw new Error("Session is not in connected state");
146+
}
147+
var payload = me.outCodecChain.transform(aEvt);
148+
ws.send( payload ); // <= send JSON/Binary data to socket server
149+
return me;
150+
};
151+
152+
me.removeHandler = function(eventName, handler){
153+
var handlers = callbacks[eventName];
154+
if (handlers instanceof Array){
155+
var index = handlers.indexOf(handler);
156+
while(index != -1){
157+
handlers.splice(index,1);
158+
index = handlers.indexOf(handler);
159+
}
160+
}
161+
};
162+
163+
me.clearHandlers = function (){
164+
callbacks = {};
165+
};
166+
167+
me.close = function (){
168+
state = 2;
169+
// TODO had a close and error dispatch event also.
170+
ws.close();
171+
};
172+
173+
function dispatch(eventName, message){
174+
dispatchToEventHandlers(callback[jet.ANY],message);
175+
dispatchToEventHandlers(callbacks[eventName],message);
176+
}
177+
178+
function dispatchToEventHandlers(chain, message){
179+
if(typeof chain === 'undefined') return; // no callbacks for this event
180+
for(var i = 0; i < chain.length; i++){
181+
chain[i]( message );
182+
}
183+
}
184+
185+
function getLogin(config){
186+
var loginEvent = jet.LoginEvent(config);
187+
var loginEncoder = (typeof config.loginEncoder === 'undefined') ? jet.Codecs.encoder : config.loginEncoder;
188+
return loginEncoder.transform(loginEvent);
189+
}
190+
191+
function applyProtocol(config){
192+
var func = (typeof config.protocol === 'undefined') ? protocol : config.protocol;
193+
ws.onmessage = func;
194+
}
195+
196+
function protocol(e){
197+
var evt = me.inCodecChain.transform(e.data);
198+
dispatch(evt.type, evt);
199+
}
200+
}
201+
}( window.jet = window.jet || {}));

jetclient-js/test/jetclient.html

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="https://github.com/menacher/java-game-server/tree/master/jetclient-js/src/jet-0.1.js"></script>
5+
<script>
6+
var sessions = [];
7+
function startWar()
8+
{
9+
var config = {
10+
user:"user",
11+
pass:"pass",
12+
connectionKey:"Zombie_ROOM_1_REF_KEY_2"
13+
};
14+
15+
for(var i=0;i<50;i++){
16+
if((i % 2) === 0){
17+
jet.sessionFactory("ws://localhost:18090/jetsocket",config,function (session){
18+
session.addHandler(jet.SESSION_MESSAGE, displayHuman);
19+
var id = window.self.setInterval(defender.bind(null,session), 500);
20+
sessions.push({session:session,id:id});
21+
});
22+
}else{
23+
jet.sessionFactory("ws://localhost:18090/jetsocket",config,function (session){
24+
session.addHandler(jet.SESSION_MESSAGE, displayZombie);
25+
var id = window.self.setInterval(zombie.bind(null,session), 500);
26+
sessions.push({session:session,id:id});
27+
});
28+
}
29+
30+
}
31+
32+
function displayHuman(e){
33+
document.getElementById("human").innerHTML="Humans Left: " + e.source;
34+
}
35+
36+
function displayZombie(e){
37+
document.getElementById("zombie").innerHTML="Zombies Left: " + (2000000000 - e.source);
38+
}
39+
40+
function defender(session){
41+
session.send(jet.nevent(jet.NETWORK_MESSAGE, [2,1]));
42+
}
43+
function zombie(session){
44+
session.send(jet.nevent(jet.NETWORK_MESSAGE, [1,2]));
45+
}
46+
}
47+
48+
function makePeace(){
49+
for(var i = 0; i < sessions.length; i++){
50+
window.clearInterval(sessions[i].id);
51+
sessions[i].session.close();
52+
}
53+
}
54+
55+
</script>
56+
</head>
57+
<body>
58+
59+
<h1>Jet Websocket</h1>
60+
<p id="human">Human</p>
61+
<p id="zombie">Zombie</p>
62+
63+
<button type="button" onclick="startWar()">Start War!</button>
64+
<button type="button" onclick="makePeace()">Make Peace</button>
65+
66+
</body>
67+
</html>

0 commit comments

Comments
 (0)