0

I am trying to use the libcurl library in C with the pushbullet api. I am trying to connect to a stream at https://stream.pushbullet.com/streaming/. The problem is once the callback function is called when it receives any data, the connection is closed. I would like to keep it running indefinitely and have it call the callback function be called every time it receives new data.

Here is the code I tried

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

int getwss_cb(char *data) {
    printf("Received data: %s\n", data);
}

int getwss(void) {
    CURL *easyhandle = curl_easy_init();

    curl_easy_setopt(easyhandle, CURLOPT_URL, "https://stream.pushbullet.com/streaming/<access-token>");
    curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, getwss_cb);
    curl_easy_perform(easyhandle);
    return 0;
}

Basically I need the getwss() function to continue running even after running getwss_cb()

Rumesh
  • 113
  • 1
  • 7
  • What do you mean by indefinitely? What is your end goal? – Austin Brunkhorst Jan 07 '18 at 11:29
  • I need it to continue running so that the getwss_cb is called everytime there is something new in the stream. The url I used will send new data as a form of notification and I need a function to run everytime there is such a notification – Rumesh Jan 07 '18 at 11:30
  • 1
    Are you sure that this API endpoint is a proper socket? I don't know this API, but it seems like this endpoint is just for generating an access token to be handed off to another socket. – Austin Brunkhorst Jan 07 '18 at 11:42
  • No I use my personal access token in the code to reach the endpoint. The actual data that is returned is a small JSON string like `{"Type": "nop"}` – Rumesh Jan 07 '18 at 11:49
  • @AustinBrunkhorst I have edited the question to make it more clear, hopefully you can understand my question now – Rumesh Jan 08 '18 at 14:22
  • Can you refer us to the documentation for this endpoint? I tried doing a search myself but couldn't find anything on this specifically. – Austin Brunkhorst Jan 08 '18 at 14:53
  • The docs talk about a web socket (was) at https://docs.pushbullet.com/#realtime-event-stream. The following answer gives the endpoint that I use https://stackoverflow.com/a/30387648. In any case I don't think there's a problem with the api. If I don't have a callback function I can see the notifications come correctly. I need to use a conditional based on the message so I need the callback function which is causing the problem the problem of ending the program as soon as it's run. – Rumesh Jan 08 '18 at 15:14

1 Answers1

1

Your callback doesn't use the correct prototype and it doesn't return the correct return code:

size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);

See the full docs explaining the callback and what it should return in the documentation for the CURLOPT_WRITEFUNCTION option.

Also note that the data that is passed to the callback is not zero terminated so you can't just printf-%s it.

Daniel Stenberg
  • 54,736
  • 17
  • 146
  • 222
  • The printf still works properly. The message is printed on screen when run. Also I don’t really need the size and other stuff from the prototype which is why I didn’t include it. Do I still need to have it? I’ll try using size_t instead of int and let you know the result when I can – Rumesh Jan 09 '18 at 04:32
  • The printf may still work *accidentally*, sure - but relying on accidental behavior is not a good idea. You **should** use the correct and exact prototype as documented as otherwise you won't be able to get the full size of the incoming data. – Daniel Stenberg Jan 09 '18 at 04:34
  • I just made the changes you suggested but the results are the same. – Rumesh Jan 09 '18 at 14:29
  • `size_t getwss_cb(char *data, size_t size1, size_t nmemb1, void *userdata1) { printf("Data Recieved!\n"); }` – Rumesh Jan 10 '18 at 14:36
  • Sorry my bad. I tried running with `return 0;` but that doesnt make any difference either. I am not entirely sure if thats the correct line that should be used though. – Rumesh Jan 12 '18 at 14:37
  • As documented, returning 0 is certainly not the right way for a continued download. – Daniel Stenberg Jan 13 '18 at 07:38
  • ‘return 1;’ doesn’t work either. What would you suggest I use for the return code? – Rumesh Jan 13 '18 at 08:26
  • I recommend doing as the documentation says: *Your callback should return the number of bytes actually taken care of.* – Daniel Stenberg Jan 13 '18 at 10:11