From 62af08dfc579738ccc7846575f34a36d6ad09b36 Mon Sep 17 00:00:00 2001
From: mcmlxxix <>
Date: Fri, 20 May 2011 18:18:12 +0000
Subject: [PATCH] JSON socket client

---
 exec/load/json-client.js | 226 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 226 insertions(+)
 create mode 100644 exec/load/json-client.js

diff --git a/exec/load/json-client.js b/exec/load/json-client.js
new file mode 100644
index 0000000000..9de2ff702f
--- /dev/null
+++ b/exec/load/json-client.js
@@ -0,0 +1,226 @@
+load("json-sock.js");
+/*     
+	JSON client  - for Synchronet 3.15a+ (2011)
+
+	-	code by mcmlxxix
+	
+	-	it is recommended to create a callback function specific to your program
+	-	and assign it to the callback property of the JSONClient object. If you do
+	-	not do this, any packets not specifically requested by your program
+	-	will be pushed into an array and sit there until you handle them
+
+	direct methods: these methods can be called directly by the main script
+	
+	-	JSONClient.cycle(); 
+	-	JSONClient.connect();
+	-	JSONClient.disconnect();
+	-	JSONClient.read();
+	-	JSONClient.write();
+	-	JSONClient.lock();
+	-	JSONClient.unlock();
+	-	JSONClient.subscribe();
+	-	JSONClient.unsubscribe();
+	-	JSONClient.status();
+	
+	indirect methods: these will generally be called automatically by the other methods
+	and you will not typically need to use them
+	
+	-	JSONClient.callback();     
+	-	JSONClient.send();
+	-	JSONClient.receive();
+	-	JSONClient.wait();
+	
+	optional arguments: if these are not supplied, 
+	the client will connect to the default server (bbs.thebrokenbubble.com)
+	
+	-	argv[0] = serverAddr;
+	-	argv[1] = serverPort;
+	
+	sample usage:
+	
+		var LOCK_READ = 1;
+		var LOCK_WRITE = 2;
+		var UNLOCK = -1;
+	
+		load("json-client.js");
+		var client=new JSONClient(myServer,myPort);
+		
+		function callback(data) {
+			myData = data;
+		}
+		
+		while(1) {
+			doSomething();
+			client.lock("mydatabase.dong",LOCK_READ);
+			var dong=client.read("mydatabase.dong");
+			client.unlock("mydatabase.dong");
+			print("look at my " + dong);
+			client.cycle();
+		}
+	
+*/
+
+function JSONClient(serverAddr,serverPort) {
+
+	this.VERSION = "$Revision$".split(' ')[1];
+	
+	this.serverAddr=serverAddr;
+    if(this.serverAddr==undefined) {
+        this.serverAddr="bbs.thebrokenbubble.com"; 
+		log(LOG_DEBUG,"using default server address: " + this.serverAddr);
+	}
+
+	this.serverPort=serverPort;
+    if(this.serverPort==undefined) {
+        this.serverPort=10088;
+		log(LOG_DEBUG,"using default server port: " + this.serverPort);
+	}
+	
+	this.settings={
+		CONNECTION_TIMEOUT:		5,
+		PING_INTERVAL:			60*1000,
+		PING_TIMEOUT:			10*1000,
+		RECV_TIMEOUT:			10
+	};
+        
+    this.socket=undefined;
+	this.callback;
+	this.updates=[];
+	
+	/* create new socket connection to server */
+    this.connect = function() {
+        this.socket=new Socket();
+		this.socket.connect(this.serverAddr,this.serverPort,this.settings.CONNECTION_TIMEOUT);
+    }
+    
+    this.disconnect = function() {
+        this.socket.close();
+    }
+    
+	/* subscribe to object updates */
+    this.subscribe=function(location) {
+		this.send({
+            operation:"SUBSCRIBE",
+            location:location,
+        },"QUERY");
+    }
+    
+    this.unsubscribe=function(location) {
+		this.send({
+            operation:"UNSUBSCRIBE",
+            location:location,
+        },"QUERY");
+    }
+	
+	/* lock an object */
+	this.lock = function(location,lock_type) {
+		this.send({
+            location:location,
+			operation:"LOCK",
+			data:lock_type
+        },"QUERY");
+	}
+	
+	/* unlock an object */ 
+	this.unlock = function(location) {
+		this.send({
+            location:location,
+			operation:"LOCK",
+			data:-1,
+        },"QUERY");
+	}
+    
+	/* read object data (lock for reading or writing, blocking) */
+    this.read=function(location,lock_type) {
+		this.send({
+            operation:"READ",
+            location:location,
+			lock:lock_type
+        },"QUERY");
+		return this.wait("RESPONSE");
+    }
+    
+	/* store object data (lock for writing) */
+    this.write=function(location,obj,lock_type) {
+        this.send({
+            operation:"WRITE",
+            location:location,
+            data:obj,
+			lock:lock_type
+        },"QUERY");
+    }
+	
+	/* package an object and send through the socket */
+	this.send=function(obj,func) {
+		var packet={
+			func:func,
+			data:obj
+		};
+		this.socket.sendJSON(packet);
+	}
+
+	/* receive a data packet */
+	this.receive=function() {
+		if(!this.socket.data_waiting) 
+			return false;
+		else
+			return this.socket.recvJSON();
+	}
+	
+	/* do not return until the expected response is received */
+	this.wait=function(func) {
+		var start = time();
+		do {
+			var response = this.receive();
+			
+			if(!response)
+				continue;
+			else if(response.func == func) 
+				return response.data;
+			else
+				this.callback(response.data);
+				
+		} while(time() - start < this.settings.RECV_TIMEOUT);
+		
+		log(LOG_ERROR,"timed out waiting for response");
+		exit();
+	}
+
+	/* check socket for data, and process it if a callback is specified */
+	this.cycle=function() {
+		var packet=this.receive();
+		if(!packet)
+			return false;
+		else if(this.callback)
+			this.callback(packet.data);
+		else 
+			this.updates.push(packet.data);
+	}
+	
+	/* retrieve the overall lock and subscription status of an object */
+	this.status=function(location) {
+		this.send({
+			operation:"STATUS",
+			location:location
+		},"QUERY");
+		return this.wait("RESPONSE");
+	}
+	
+	this.connect();
+	log(LOG_INFO,"JSON client initialized (v" + this.VERSION + ")");
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- 
GitLab