wildfire chat server source initial submit
This commit is contained in:
+50
@@ -0,0 +1,50 @@
|
||||
// this example demonstrates a way to keep field casing (as defined within .proto files)
|
||||
// while still having virtual getters and setters for the camel cased counterparts.
|
||||
|
||||
/*eslint-disable strict, no-console*/
|
||||
var protobuf = require("..");
|
||||
|
||||
var proto = "syntax=\"proto3\";\
|
||||
message MyMessage {\
|
||||
string some_field = 1;\
|
||||
}";
|
||||
|
||||
var root = protobuf.parse(proto, { keepCase: true }).root; // or use Root#load
|
||||
|
||||
// converts a string from underscore notation to camel case
|
||||
function toCamelCase(str) {
|
||||
return str.substring(0,1) + str.substring(1).replace(/_([a-z])(?=[a-z]|$)/g, function($0, $1) { return $1.toUpperCase(); });
|
||||
}
|
||||
|
||||
// adds a virtual alias property
|
||||
function addAliasProperty(type, name, aliasName) {
|
||||
if (aliasName !== name)
|
||||
Object.defineProperty(type.ctor.prototype, aliasName, {
|
||||
get: function() { return this[name]; },
|
||||
set: function(value) { this[name] = value; }
|
||||
});
|
||||
}
|
||||
|
||||
// this function adds alternative getters and setters for the camel cased counterparts
|
||||
// to the runtime message's prototype (i.e. without having to register a custom class):
|
||||
function addVirtualCamelcaseFields(type) {
|
||||
type.fieldsArray.forEach(function(field) {
|
||||
addAliasProperty(type, field.name, toCamelCase(field.name));
|
||||
});
|
||||
type.oneofsArray.forEach(function(oneof) {
|
||||
addAliasProperty(type, oneof.name, toCamelCase(oneof.name));
|
||||
});
|
||||
return type;
|
||||
}
|
||||
|
||||
var MyMessage = addVirtualCamelcaseFields(root.lookup("MyMessage"));
|
||||
|
||||
var myMessage = MyMessage.create({
|
||||
some_field /* or someField */: "hello world"
|
||||
});
|
||||
|
||||
console.log(
|
||||
"someField:", myMessage.someField,
|
||||
"\nsome_field:", myMessage.some_field,
|
||||
"\nJSON:", JSON.stringify(myMessage)
|
||||
);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// This example shows how decorators can be used with plain JavaScript. It's otherwise identical to
|
||||
// the README example.
|
||||
|
||||
/*eslint-disable strict, no-console*/
|
||||
var protobuf = require("../light");
|
||||
|
||||
var Type = protobuf.Type,
|
||||
Field = protobuf.Field,
|
||||
OneOf = protobuf.OneOf;
|
||||
|
||||
function AwesomeSubMessage(properties) {
|
||||
protobuf.Message.call(this, properties);
|
||||
}
|
||||
|
||||
(AwesomeSubMessage.prototype = Object.create(protobuf.Message)).constructor = AwesomeSubMessage;
|
||||
|
||||
Field.d(1, "string", "optional", "awesome default string")(AwesomeSubMessage.prototype, "awesomeField");
|
||||
|
||||
var AwesomeEnum = {
|
||||
ONE: 1,
|
||||
TWO: 2
|
||||
};
|
||||
|
||||
Type.d("SuperAwesomeMessage")(AwesomeMessage);
|
||||
function AwesomeMessage(properties) {
|
||||
protobuf.Message.call(this, properties);
|
||||
}
|
||||
|
||||
(AwesomeMessage.prototype = Object.create(protobuf.Message)).constructor = AwesomeMessage;
|
||||
|
||||
Field.d(1, "string", "optional", "awesome default string")(AwesomeMessage.prototype, "awesomeField");
|
||||
Field.d(2, AwesomeSubMessage)(AwesomeMessage.prototype, "awesomeSubMessage");
|
||||
Field.d(3, AwesomeEnum, "optional", AwesomeEnum.ONE)(AwesomeMessage.prototype, "awesomeEnum");
|
||||
OneOf.d("awesomeSubMessage", "awesomeEnum")(AwesomeMessage.prototype, "which");
|
||||
|
||||
// example code
|
||||
var message = new AwesomeMessage({ awesomeField: "hello" });
|
||||
var buffer = AwesomeMessage.encode(message).finish();
|
||||
var decoded = AwesomeMessage.decode(buffer);
|
||||
|
||||
console.log(decoded);
|
||||
console.log("internal name: " + AwesomeMessage.$type.name);
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// this example demonstrates how to use the reader/writer interface directly to read and write the
|
||||
// protobuf wire format.
|
||||
|
||||
/*eslint-disable strict, no-console*/
|
||||
var protobuf = require("../runtime"); // require("protobufjs/runtime");
|
||||
|
||||
// writing
|
||||
var buffer = protobuf.Writer.create()
|
||||
.uint32((1 << 3 | 2) >>> 0) // id 1, wireType 2
|
||||
.string("hello world!")
|
||||
.finish();
|
||||
|
||||
// reading
|
||||
var reader = protobuf.Reader.create(buffer);
|
||||
while (reader.pos < reader.len) {
|
||||
var tag = reader.uint32();
|
||||
switch (/*id*/ tag >>> 3) {
|
||||
case 1:
|
||||
console.log(reader.string());
|
||||
break;
|
||||
default:
|
||||
reader.skipType(/*wireType*/ tag & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
// this example demonstrates how to consume a streaming rpc service.
|
||||
|
||||
/*eslint-disable strict, no-console*/
|
||||
var protobuf = require("..");
|
||||
|
||||
// Load a definition with services:
|
||||
|
||||
var root = protobuf.Root.fromJSON({
|
||||
nested: {
|
||||
Greeter: {
|
||||
methods: {
|
||||
"SayHello": {
|
||||
requestType: "Hello",
|
||||
requestStream: true,
|
||||
responseType: "World",
|
||||
responseStream: true
|
||||
}
|
||||
}
|
||||
},
|
||||
Hello: {
|
||||
fields: {
|
||||
name: {
|
||||
type: "string",
|
||||
id: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
World: {
|
||||
fields: {
|
||||
message: {
|
||||
type: "string",
|
||||
id: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Get its types:
|
||||
|
||||
var Greeter = root.lookup("Greeter"),
|
||||
Hello = root.lookup("Hello"),
|
||||
World = root.lookup("World");
|
||||
|
||||
// Provide a stream-aware RPC implementation:
|
||||
|
||||
var greeter = Greeter.create(/* rpcImpl */ (function() { // API documentation: Service#create
|
||||
var ended = false;
|
||||
return function myRPCImpl(method, requestData, callback) {
|
||||
if (ended)
|
||||
return;
|
||||
if (!requestData) {
|
||||
ended = true;
|
||||
return;
|
||||
}
|
||||
// in a real-world scenario, the client would now send requestData to a server using some
|
||||
// sort of transport layer (i.e. http), wait for responseData and call the callback.
|
||||
performRequestOverTransportChannel(requestData, function(responseData) {
|
||||
callback(null, responseData);
|
||||
});
|
||||
};
|
||||
})(), /* requestDelimited? */ true, /* responseDelimited? */ true);
|
||||
|
||||
// examplary server-side code for the sake of this example
|
||||
function performRequestOverTransportChannel(requestData, callback) {
|
||||
setTimeout(/* simulated delay */function() {
|
||||
// 1. server decodes the request
|
||||
var request = Hello.decodeDelimited(requestData);
|
||||
// 2. server handles the request and creates a response
|
||||
var response = { message: "Hello " + request.name };
|
||||
setTimeout(/* simulated delay */function() {
|
||||
// 3. server encodes and sends the response
|
||||
callback(World.encodeDelimited(response).finish());
|
||||
}, Math.random() * 250);
|
||||
}, Math.random() * 250);
|
||||
}
|
||||
|
||||
// Listen for events:
|
||||
|
||||
greeter.on("data", function(response, method) {
|
||||
console.log("data in " + method.name + ":", response.message);
|
||||
});
|
||||
|
||||
greeter.on("end", function() {
|
||||
console.log("end");
|
||||
});
|
||||
|
||||
greeter.on("error", function(err, method) {
|
||||
console.log("error in " + method.name + ":", err);
|
||||
});
|
||||
|
||||
// Call methods:
|
||||
|
||||
greeter.sayHello({ name: "one" });
|
||||
greeter.sayHello(Hello.create({ name: "two" })); // or use runtime messages
|
||||
|
||||
// Listen to and emit your own events if you like:
|
||||
|
||||
greeter.on("status", function(code, text) {
|
||||
console.log("custom status:", code, text);
|
||||
});
|
||||
|
||||
greeter.emit("status", 200, "OK");
|
||||
|
||||
// And, if applicable, end the service when you are done:
|
||||
|
||||
setTimeout(function() {
|
||||
greeter.end();
|
||||
// ^ Signals rpcImpl that the service has been ended client-side by calling it with a null buffer.
|
||||
// Likewise, rpcImpl can also end the stream by calling its callback with an explicit null buffer.
|
||||
greeter.sayHello({ name: "three" }, function(err) {
|
||||
console.error("this should fail: " + err.message);
|
||||
});
|
||||
}, 501);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// this example demonstrates how to traverse through a root instance by calling a custom function
|
||||
// for each message type within.
|
||||
|
||||
/*eslint-disable strict, no-console*/
|
||||
var protobuf = require(".."); // require("protobufjs");
|
||||
|
||||
// traverse-types.proto
|
||||
var proto = "syntax=\"proto3\";\
|
||||
package example;\
|
||||
message Foo {\
|
||||
string a = 1;\
|
||||
}\
|
||||
message Bar {\
|
||||
uint32 b = 1;\
|
||||
\
|
||||
message Inner {\
|
||||
bytes c = 1;\
|
||||
}\
|
||||
}";
|
||||
|
||||
// the following is loading a string.
|
||||
// in a real application, it'd be more like protobuf.load("traverse-types.proto", ...)
|
||||
protobuf.parse.filename = "traverse-types.proto";
|
||||
var root = protobuf.parse(proto).root;
|
||||
|
||||
function traverseTypes(current, fn) {
|
||||
if (current instanceof protobuf.Type) // and/or protobuf.Enum, protobuf.Service etc.
|
||||
fn(current);
|
||||
if (current.nestedArray)
|
||||
current.nestedArray.forEach(function(nested) {
|
||||
traverseTypes(nested, fn);
|
||||
});
|
||||
}
|
||||
|
||||
traverseTypes(root, function(type) {
|
||||
console.log(
|
||||
type.constructor.className + " " + type.name
|
||||
+ "\n fully qualified name: " + type.fullName
|
||||
+ "\n defined in: " + type.filename
|
||||
+ "\n parent: " + type.parent + " in " + type.parent.filename
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user