I currently use the below callback to check the PAYLOAD of incoming MQTT messages, but does anyone know how I could continue to do this but also find messages coming under a specific TOPIC?
void callback(char * topic, byte * payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
if (!strcmp(p, "home")) {
Particle.publish(DEVICE_NAME, HOME_MSSG, 60, PRIVATE);
} else if (!strcmp(p, "chome")) {
Particle.publish(DEVICE_NAME, CHOME_MSSG, 60, PRIVATE);
}
}
The topic can be handled in pretty much the same way as the payload; e.g.
if (!strcmp(topic, "thisIsATopic")) {
// do something
}
Note that the payload is copied for two reasons:
The buffer is reused once the callback returns (so if you store that pointer and refer to it later it may not contain what you expect).
The message is binary so it is important to ensure a \0 is added to the end if using functions like strcmp (to avoid overruns).
It looks like the library you are using copies the topic so you should be fine using that as-is (unlike with some other libraries).
Related
I'm learning gRPC using the official doc, but found the method signature of client-streaming and bidirectional-streaming very confusing (the two are the same).
From the doc here, the function takes StreamObserver<ResponseType> as the input parameter and returns a StreamObserver<ResponseType> instance, as the following:
public StreamObserver<RequestType> bidirectionalStreamingExample(
StreamObserver<ResponseType> responseObserver)
But in my mind, it should take the RequestType type as input and returns the ResponseType type:
public StreamObserver<ResponseType> bidirectionalStreamingExample(
StreamObserver<RequestType> responseObserver)
This confuses me very much and I'm actually a little surprised that the answer didn't prompt up when I search is in google, I thought many people would have the same question. Am I missing something obvious here? Why would gRPC defines the signature like this?
Your confusion probably stems from being used to REST or non-streaming frameworks, where request-response is often mapped to a function's parameter-return. The paradigm shift here is that you're no longer supplying request-response, but rather channels to drop requests and responses. If you've studied C or C++, it's very much like going from
int get_square_root(int input);
to
void get_square_root(int input, int& output);
See how output's now a parameter? But in case that makes no sense at all (my fault :-) here's a more organic path:
Server Streaming
Let's start with the server streaming stub, even if your eventual goal is client streaming.
public void serverStreamingExample(
RequestType request,
StreamObserver<ResponseType> responseObserver)
Q: Why is the "response" in the parameter list? A: It's not the response that's in the parameter list, but rather a channel to feed the eventual response to. So for example:
public void serverStreamingExample(
RequestType request,
StreamObserver<ResponseType> responseObserver) {
ResponseType response = processRequest(request);
responseObserver.onNext(response); // this is the "return"
responseObserver.onCompleted();
}
Why? Because, the point of streaming is to keep alive a channel on which responses can keep flowing through. If you could only return 1 response and that's that, the function's done, then that's not a stream. By supplying a channel, you as the developer can choose to pass it along as needed, feeding it as many responses as you'd like via onNext() until you're satisfied and call onCompleted().
Client Streaming
Now, let's move on to the client streaming stub:
public StreamObserver<RequestType> clientStreamingExample(
StreamObserver<ResponseType> responseObserver)
Q: Wait, what! We know why the response is in the parameter list now, but how does it make sense to return a request? A: Again, we're not actually returning a request, but a channel for the client to drop requests! Why? Because the point of client streaming is to allow the client to supply requests in pieces. It can't do that with a single, traditional call to the server. So here's one way this can be implemented:
class ClientStreamingExample {
int piecesRcvd = 0;
public StreamObserver<RequestType> myClientStreamingEndpoint(
StreamObserver<ResponseType> responseObserver) {
return new StreamObserver<RequestType>() {
#Override
public void onNext(RequestType requestPiece) {
// do whatever you want with the request pieces
piecesRcvd++;
}
#Override
public void onCompleted() {
// when the client says they're done sending request pieces,
// send them a response back (but you don't have to! or it can
// be conditional!)
ResponseType response =
new ResponseType("received " + piecesRcvd + " pieces");
responseObserver.onNext(response);
responseObserver.onCompleted();
piecesRcvd = 0;
}
#Override
public void onError() {
piecesRcvd = 0;
}
};
}
}
You might have to spend a little time studying this to fully understand, but basically, since the client may now send a stream of requests, you have to define handlers for each request piece, as well as handlers for the client saying it's done or errored out. (In my example, I have the server only respond when the client says it's done, but you're free to do anything you want. You can even have the server respond even before the client says it's done or not respond at all.)
Bidirectional Streaming
This isn't really a thing! :-) What I mean is, tutorials just mean to point out that nothing's stopping you from implementing exactly the above, just on both sides. So you end up with 2 applications that send and receive requests in pieces, and send and receive responses. They call this setup bidirectional streaming, and they're correct to, but it's just a little misleading since it's not doing anything technically different from client streaming. That's exactly why the signatures are the same. IMHO, tutorials should just mention a note like I have here, rather than repeat the stub.
Optional: Just for "fun"...
We began with the C++ analogy of going from
int get_square_root(int input); // "traditional" request-response
to
void get_square_root(int input, int& output); // server streaming
Do we want to carry on this analogy? Of course we do.
🎵 Hello, C++ function pointers, my old friend... 🎶
void (*fnPtr)(int) get_square_root_fn(int& output); // client streaming
And a demonstration of its use(lessness):
int main() { // aka the client
int result;
void (*fnPtr)(int) = server.get_square_root_fn(result);
fnPtr(2);
std::cout << result << std::endl; // 1.4142 assuming the fn actually does sqrt
}
I have written a server using QTcpSocket. The server handles the POST request from client app. I use the content-length field to determine the end of the request body. The code is as follows:
int length = 0;
QString line = "";
while(this->canReadLine())
{
line = this.readLine();
if(line.contains("Content-Length"))
{
length = line.split(':')[1].toInt();
}
if(line == "\r\n")
{
break;
}
}
for(; this.bytesAvailable() < length; ){}
QString requestBody = this.readAll();
It works in my localhost. But when it is run on remote server, bytesAvailable always returns a fixed value: 0 or 2896. Is there something wrong in my code or the network is causing that?
The bytesAvailable() function only tells you how many bytes are in the internal buffer of QTcpSocket, it does not instruct it to look for more data coming across the network. Calling this function repeatedly is thus a pointless exercise and can cause your program to hang.
What you are trying to do is wait for more data to arrive. To do this, you must let your program go back to the event loop or call one of the blocking functions, like waitForReadyRead()
EDIT:
If you're using standard HTTP processing, also consider using QNetworkAccessManager along with QNetworkReply to simplify the data retrieval process.
As far as I understand one has two options to port a C program to Native Client:
Implement a number of initializing functions like PPP_InitializeModule and PPP_GetInterface.
Simply pass your main function to PPAPI_SIMPLE_REGISTER_MAIN.
So the question is how can I implement JS message handling (handle messages emitted by JS code in native code) in the second case?
Take a look at some of the examples in the SDK in examples/demo directory: earth, voronoi, flock, pi_generator, and life all use ppapi_simple.
Here's basically how it works:
When using ppapi_simple, all events (e.g. input events, messages from JavaScript) are added to an event queue. The following code is from the life example (though some of it is modified and untested):
PSEventSetFilter(PSE_ALL);
while (true) {
PSEvent* ps_event;
/* Process all waiting events without blocking */
while ((ps_event = PSEventTryAcquire()) != NULL) {
earth.HandleEvent(ps_event);
PSEventRelease(ps_event);
}
...
}
HandleEvent then determines what kind of event it is, and handles it in an application specific way:
void ProcessEvent(PSEvent* ps_event) {
...
if (ps_event->type == PSE_INSTANCE_HANDLEINPUT) {
...
} else if (ps_event->type == PSE_INSTANCE_HANDLEMESSAGE) {
// ps_event->as_var is a PP_Var with the value sent from JavaScript.
// See docs for it here: https://developers.google.com/native-client/dev/pepperc/struct_p_p___var
if (ps_event->as_var->type == PP_VARTYPE_STRING) {
const char* message;
uint32_t len;
message = PSInterfaceVar()->VarToUtf8(ps_event->as_var, &len);
// Do something with the message. Note that it is NOT null-terminated.
}
}
To send messages back to JavaScript, use the PostMessage function on the messaging interface:
PP_Var message;
message = PSInterfaceVar()->VarFromUtf8("Hello, World!", 13);
// Send a string message to JavaScript
PSInterfaceMessaging()->PostMessage(PSGetInstanceId(), message);
// Release the string resource
PSInterfaceVar()->Release(message);
You can send and receive other JavaScript types too: ints, floats, arrays, array buffers, and dictionaries. See also PPB_VarArray, PPB_VarArrayBuffer and PPB_VarDictionary interfaces.
VaComm component encapsulates communication with external devices through COM port. My program is communicating with measuring device using following code:
void Form::OnButton_Click()
{
VaComm1->PortNum = param.serialComm.port;
VaComm1->Open();
VaComm1->WriteText("bla bla\r\n");
Sleep(3000);
VaComm1->WriteText("another bla bla");
}
I have set OnRxChar event handler (through form designer) which looks like this:
void __fastcall TForm_Main::VaComm1RxChar(TObject *Sender, int Count)
{
AnsiString str = VaComm1->ReadText();
if (!str.IsEmpty())
{
// process received data
}
}
Problem is that this event is not fired even when data were received (can be checked through calling TVaComm::ReadText method in infinite loop). Also sending of two commands to connected device was successfull (can be seen on device display). What else is needed beside opening COM port to receive OnRxChar events when there are some data in input buffer? I also don't understand what is the purpose of sibling component TVaBuffer? Currently i am not using it and can receive data through method ReadText (as i have written above).
Most CommPort components I have seen depend on the calling thread having an active message loop in order to fire asynchronous events. In this case, your main thread is blocked from processing new messages until OnButon_Click() exits. Try something more like this instead:
void Form::OnButton_Click()
{
VaComm1->PortNum = param.serialComm.port;
VaComm1->Open();
VaComm1->WriteText("bla bla\r\n");
}
void __fastcall TForm_Main::VaComm1RxChar(TObject *Sender, int Count)
{
AnsiString str = VaComm1->ReadText();
if (!str.IsEmpty())
{
// process received data
if (str is a reply you are expecting)
VaComm1->WriteText("another bla bla");
}
}
How do you use std.typecons.RefCounted!(T) to make a reference-counted object in D?
I've tried to figure out what std.array.Array does internally by looking at the source, but while I can read the source, I just can't figure what a "payload" is or how it all works when there's things like bitwise struct copying involved, as well as why some things are duplicated in the internal and external structure.
Could anyone provide an example or a link on how to use it to, say, wrap a simple Win32 HANDLE?
Thanks!
Disclaimer: I haven't tested my claims, just read the documentation.
Payload is referring to what is being stored. In your case the payload is the Win32 HANDLE. Since HANDLE is just an integer you wouldn't want to do:
auto refHandle = RefCounted!HANDLE(WhatGetsMeAHandle());
Because a Windows function will need to be called when the handle goes out of scope.
In std.containers.Array what you saw was a struct called Payload, which had a field called _payload. The structure is going to be the storage of the data, accessed through _payload. This provides a level of indirection to be utilized later.
You will notice that RefCounted is actually used on the Array structure. This means the destructor for that struct will only be called when the reference count is 0. So the ~this() inside of Payload is where you would want to clean up the your HANDLE.
What is happening: since struct is a value type, every time the structure goes out of scope the destructor is called, there isn't one for Array, but Payload is wrapped in a RefCounted, the destructor for RefCounted!Payload is also called. And only when the reference count reaches zero is the destructor for Payload itself called.
Now, RefCounted itself has reference semantics, this means that having an Array a, you can then assign to auto b = a; and everything will be copied over, but RefCounted has a postblits defined meaning the data will not be copied, but the reference count will be
incremented.
I will now try and provide you with a wrapper outline for what you want. It will probably help you visualize the information above, but it may not be entirely correct. Let me know if something needs fixing.
struct MyWinWrapper {
struct Payload {
HANDLE _payload;
this(HANDLE h) { _payload = h; }
~this() { freeHandleHere(_payload); }
// Should never perform these operations
this(this) { assert(false); }
void opAssign(MyWinWrapper.Payload rhs) { assert(false); }
}
private alias RefCounted!(Payload, RefCountedAutoInitialize.no) Data;
private Data _data;
this(HANDLE h) { _data = Data(h); }
}
Since there is no default constructor for a struct you will probably want to provide a free function that returns this structure.