Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

have any sample for websocket client ? #66

Open
jobsguo opened this issue Nov 30, 2017 · 2 comments
Open

have any sample for websocket client ? #66

jobsguo opened this issue Nov 30, 2017 · 2 comments

Comments

@jobsguo
Copy link

jobsguo commented Nov 30, 2017

hi,do you have any sample for websocket client which connect monaserver.
because I want to connect monaserver whit websocket in android /ios.
thanks.

@jobsguo
Copy link
Author

jobsguo commented Nov 30, 2017

Now,I have get how to recevie message,but how to parse message?
eg when I send message with websocket client suc as
"{\"getLiveNameList\",\"null\"}"
I parse recv message in below function,but just get the json name,can not get the json value

void WSSession::readMessage(Exception& ex, DataReader& reader, UInt8 responseType) { string value; reader.readString(value); }

@thomasjammet
Copy link
Contributor

thomasjammet commented Dec 5, 2017

Hi,

I see that you are working on the C++ side, why don't you use lua directly? You will find the documentation on this page.

Though if you really want to go with c++ you should download MonaServer2 and compile MonaTiny (the most up-to-date version of Mona but without lua support for now). Then there are 2 ways to read your arguments in the MonaTiny::onInvocation function :

  1. Use readBoolean, readDate, readNumber, readString etc... to read simple arguments sent in an array. For example you can send ["testCall", "hello", 42, "2005-01-01 12:00:00", true] and this will set "testCall" as the function name argument and the others will be available in the arguments variable. Here is a code example :
bool MonaTiny::onInvocation(Exception& ex, Client& client, const string& name, DataReader& arguments, UInt8 responseType) {
	// on client message, returns "false" if "name" message is unknown
	DEBUG(name, " call from ", client.protocol, " to ", client.path.empty() ? "/" : client.path);

	while (arguments.available()) {
		UInt8 type = arguments.nextType();

		bool boolResult(false);
		Date dateResult;
		Int64 numberResult;
		string stringResult;
		switch (type) {
		case DataReader::BOOLEAN:
			arguments.readBoolean(boolResult);
			INFO("Bool received : ", boolResult)
			break;
		case DataReader::DATE:
			arguments.readDate(dateResult);
			INFO("Date received : ", dateResult.format(Date::FORMAT_HTTP, stringResult))
			break;
		case DataReader::NUMBER:
			arguments.readNumber(numberResult);
			INFO("Number received : ", numberResult)
			break;
		case DataReader::STRING:
			arguments.readString(stringResult);
			INFO("String received : ", stringResult)
			break;
		default:
			INFO("Unhandled type : ", type)
			arguments.next();
			break;
		}
	}

	return true; // set to true to accept the function call for every function name
} 
  1. Now if you want to parse a more complicate structure you will have to use the DataWriter API. You will find below the source code to parse socket addresses stored in the "addresses" property of the data ["testCall2", "ignored", {"addresses":["127.0.0.1:1234", "192.168.0.1:1235"], "ignored2" : 0}]

onInvocation function :

bool MonaTiny::onInvocation(Exception& ex, Client& client, const string& name, DataReader& arguments, UInt8 responseType) {
	// on client message, returns "false" if "name" message is unknown
	DEBUG(name, " call from ", client.protocol, " to ", client.path.empty() ? "/" : client.path);

	TestWriter test;
	arguments.read(test);
	for (auto itAddr : test.addresses) 
		INFO("Address received : ", itAddr)

	return true;
} 

TestWriter structure :

	struct TestWriter : DataWriter, virtual Object {

		TestWriter() {}

		std::set<SocketAddress> addresses;

		UInt64 beginObject(const char* type = NULL) { return 0; }
		void   writePropertyName(const char* value) { _property.assign(value); }
		void   endObject() {}

		void  clear() { _property.clear(); addresses.clear(); }

		UInt64 beginArray(UInt32 size) { return 0; }
		void   endArray() { }

		UInt64 beginObjectArray(UInt32 size) { return 0; }

		void writeString(const char* value, UInt32 size) { set(value, size); }
		void writeNumber(double value) { set(String(value)); }
		void writeBoolean(bool value) { set(value ? "true" : "false"); }
		void writeNull() { set(EXPAND("null")); }
		UInt64 writeDate(const Date& date) { set(String(date)); return 0; }
		UInt64 writeBytes(const UInt8* data, UInt32 size) { set(STR data, size); return 0; }

	private:

		template <typename ...Args>
		void set(Args&&... args) {
			if (_property == "addresses") {
				string address(std::forward<Args>(args)...);
				SocketAddress sock;
				Exception ex;
				if (!sock.set(ex, address)) {
					WARN("Error while reading address : ", ex)
						return;
				}
				addresses.emplace(sock);
			}
		}

		std::string	_property;
	};

I hope this will help you. For information you can test fast with the Simple Web Socket Firefox addon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants