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

Read JSON document from socket and file descriptor #92

Open
Lucas286 opened this issue Oct 1, 2020 · 3 comments
Open

Read JSON document from socket and file descriptor #92

Lucas286 opened this issue Oct 1, 2020 · 3 comments

Comments

@Lucas286
Copy link

Lucas286 commented Oct 1, 2020

Hello,
I really like the library. Is there any safe way to load a document from a socket having its descriptor? How do I deal with framing and merging two different documents?

@penduin
Copy link
Member

penduin commented Oct 1, 2020

Glad you're enjoying it! Look into the WJReader docs (also on the wiki here on github) about reader callbacks to get data from anywhere, including a socket. It wouldn't hurt to accumulate some examples/helpers if you want to contribute what you come up with. (The same goes for WJWriter, you can write to a socket or anything else with a pretty simple callback.)

I'm not sure what you're asking when it comes to merges.
WJEMergeObjects handles stuff like:
{ a:1, b:2 } + { c:3 } = { a: 1, b:2, c:3 }
If by framing you mean something more like:
{ name:"shmoe" } + { age:123, smart:false } = { name: "shmoe", "attrs": { age:123, smart:false } }
then you'll want something like:
WJERename(from, "attrs");
WJEAttach(into, from);

Is any of that helpful?

@Lucas286
Copy link
Author

Lucas286 commented Oct 6, 2020

In general, it is about non-blocking reading of the data stream from the socket. This stream is a json document. There can be many documents one after the other. Currently I have solved it using Newline Delimited JSON (ndjson.org). It's just that individual JSON documents are separated by '\ n'. Then reading and parsing documents is done with the following code:

// ipc client
typedef struct
{
	int                       fd;
	struct timespec   timeout;
	char*                   buff;
	int                        buff_idx;

} client_t;

// ****************************************************************************************************

int load_client_ndjson(client_t *client)
{
	struct timeval t;
	fd_set fdr;

	do
	{
		bzero(&t, sizeof(t));
		FD_ZERO(&fdr);
		FD_SET(client->fd, &fdr);

		if (select(client->fd + 1, &fdr, NULL, NULL, &t) > 0)
		{
			if (FD_ISSET(client->fd, &fdr))
			{
				char c;

				if (read(client->fd, &c, 1))
				{
					client->buff[client->buff_idx++] = c;
				}
				else
				{
					// socket disconected
					ipc_close_client(client);
					break;
				}

				if (c == '\n')
				{
					return 1;
				}
			}
		}
		else
		{
			return 0;
		}
	}
	while (client->buff_idx <  IPC_TCP_BUFFER_SIZE - 1);

	// overflow, clear buffer
	bzero(client->buff, IPC_TCP_BUFFER_SIZE);
	client->buff_idx = 0;

	return 0;

}

// ****************************************************************************************************

void ipc_client_process(client_t *client)
{
       // here descriptor i ready to read, but I am not sure that the entire document is readable

	// load full Newline Delimited JSON
	if (load_client_ndjson(client))
	{
               WJElement ndjson = NULL;

		ndjson = WJEParse(client->buff);

		if (ndjson)
		{
                       // wjelement operations....

                }
            
        }

}

I was wondering if this could be solved in a different way without using NDJSON.

@minego
Copy link
Member

minego commented Oct 6, 2020 via email

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

3 participants