First go at implementing rooms. A test passes that appears to exercise them.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4017 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										83
									
								
								core/ssb.js
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								core/ssb.js
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| "use strict"; | ||||
| var g_wants_requests = {}; | ||||
| var g_database = new Database('core'); | ||||
| let g_attendants = {}; | ||||
| const k_use_create_history_stream = false; | ||||
| const k_blobs_concurrent_target = 8; | ||||
|  | ||||
| @@ -72,7 +73,28 @@ function storeMessage(message) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ssb.addEventListener('connections', function(change, connection) { | ||||
| function tunnel_attendants(request) { | ||||
| 	if (request.message.type !== 'state') { | ||||
| 		throw Error('Unexpected type: ' + request.message.type); | ||||
| 	} | ||||
| 	let state = new Set(request.message.ids); | ||||
| 	for (let id of state) { | ||||
| 		request.add_room_attendant(id); | ||||
| 	} | ||||
| 	request.more(function attendants(message) { | ||||
| 		if (message.message.type === 'joined') { | ||||
| 			request.add_room_attendant(message.message.id); | ||||
| 			state.add(message.message.id); | ||||
| 		} else if (message.message.type === 'left') { | ||||
| 			request.remove_room_attendant(message.message.id); | ||||
| 			state.delete(message.message.id); | ||||
| 		} else { | ||||
| 			throw Error('Unexpected type: ' + message.type); | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
|  | ||||
| ssb.addEventListener('connections', function on_connections_changed(change, connection) { | ||||
| 	if (change == 'add') { | ||||
| 		var sequence = get_latest_sequence_for_author(connection.id); | ||||
| 		if (k_use_create_history_stream) { | ||||
| @@ -89,12 +111,17 @@ ssb.addEventListener('connections', function(change, connection) { | ||||
| 			}); | ||||
| 		} else { | ||||
| 			if (connection.is_client) { | ||||
| 				connection.send_json({'name': ['tunnel', 'isRoom'], 'args': [], 'type': 'source'}, function tunnel_is_room(request) { | ||||
| 					if (request.message) { | ||||
| 						connection.send_json({'name': ['room', 'attendants'], 'args': [], 'type': 'source'}, tunnel_attendants); | ||||
| 					} | ||||
| 				}); | ||||
| 				connection.send_json({"name": ["ebt", "replicate"], "args": [{"version": 3, "format": "classic"}], "type": "duplex"}, ebtReplicateClient); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		connection.active_blob_wants = {}; | ||||
| 		connection.send_json({'name': ['blobs', 'createWants'], 'type': 'source', 'args': []}, function(message) { | ||||
| 		connection.send_json({'name': ['blobs', 'createWants'], 'type': 'source', 'args': []}, function on_blob_create_wants(message) { | ||||
| 			Object.keys(message.message).forEach(function(id) { | ||||
| 				if (message.message[id] < 0) { | ||||
| 					if (g_wants_requests[connection.id]) { | ||||
| @@ -129,6 +156,8 @@ ssb.addEventListener('connections', function(change, connection) { | ||||
| 		}); | ||||
| 	} else if (change == 'remove') { | ||||
| 		print('REMOVE', connection.id); | ||||
| 		notify_attendant_changed(connection.id, 'left'); | ||||
| 		delete g_attendants[connection.id]; | ||||
| 		delete g_wants_requests[connection.id]; | ||||
| 	} else { | ||||
| 		print('CHANGE', change); | ||||
| @@ -191,13 +220,59 @@ ssb.addRpc(['blobs', 'get'], function(request) { | ||||
| }); | ||||
|  | ||||
| ssb.addRpc(['gossip', 'ping'], function(request) { | ||||
| 	request.more(function(message) { | ||||
| 	request.more(function ping(message) { | ||||
| 		message.send_json(Date.now()); | ||||
| 	}); | ||||
| }); | ||||
|  | ||||
| ssb.addRpc(['tunnel', 'isRoom'], function(request) { | ||||
| 	request.send_json(false); | ||||
| 	request.send_json(true); | ||||
| }); | ||||
|  | ||||
| function notify_attendant_changed(id, type) { | ||||
| 	for (let r of Object.values(g_attendants)) { | ||||
| 		try { | ||||
| 			r.send_json({ | ||||
| 				type: type, | ||||
| 				id: id, | ||||
| 			}); | ||||
| 		} catch (e) { | ||||
| 			print(`Removing ${r.connection.id} from g_attendants in ${type}.`, e); | ||||
| 			delete g_attendants[r.connection.id]; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ssb.addRpc(['room', 'attendants'], function(request) { | ||||
| 	let ids = Object.keys(g_attendants).sort(); | ||||
| 	request.send_json({ | ||||
| 		type: 'state', | ||||
| 		ids: ids, | ||||
| 	}); | ||||
| 	notify_attendant_changed(request.connection.id, 'joined'); | ||||
| 	g_attendants[request.connection.id] = request; | ||||
| }); | ||||
|  | ||||
| ssb.addRpc(['tunnel', 'connect'], function(request) { | ||||
| 	if (!request.args[0].origin && | ||||
| 		request.args[0].portal && | ||||
| 		request.args[0].target) { | ||||
| 		let target_connection = ssb.getConnection(request.args[0].target); | ||||
| 		let target_request_number = target_connection.send_json({ | ||||
| 			'name': ['tunnel', 'connect'], | ||||
| 			'args': [{ | ||||
| 				'origin': request.connection.id, | ||||
| 				'portal': request.args[0].portal, | ||||
| 				'target': request.args[0].target, | ||||
| 			}], | ||||
| 			'type': 'duplex', | ||||
| 		}); | ||||
| 		ssb.tunnel(request.connection, -request.request_number, target_connection, target_request_number); | ||||
| 	} else if (request.args[0].origin && | ||||
| 		request.args[0].portal && | ||||
| 		request.args[0].target) { | ||||
| 		ssb.createTunnel(request.connection, -request.request_number, request.args[0].origin); | ||||
| 	} | ||||
| }); | ||||
|  | ||||
| function ebtReplicateSendClock(request, have) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user