Here is an example of gRPC server streaming using C programming language:

#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "streaming.grpc-c.h"

#define SERVER_ADDRESS "localhost:50051"

typedef struct {
  grpc_server *server;
} server_data;

typedef struct {
  int message_id;
  char *message;
  int delay;
} message_data;

static void *run_server(void *arg) {
  server_data *data = (server_data *)arg;
  grpc_server_start(data->server);
  grpc_server_wait(data->server);
  return NULL;
}

static void send_messages(streaming__pb__MessageService__Service *service,
                          grpc_server_context *context, void *arg) {
  message_data *data = (message_data *)arg;

  streaming__pb__Message message = STREAMING__PB__MESSAGE__INIT;
  message.id = data->message_id;
  message.text = data->message;

  streaming__pb__MessageResponse response = STREAMING__PB__MESSAGE_RESPONSE__INIT;

  grpc_op op;
  grpc_op *ops;
  grpc_op_status_metadata status;
  grpc_metadata meta;
  grpc_metadata_array meta_array;
  grpc_call *call;
  grpc_call_error call_error;
  grpc_byte_buffer *buffer;
  grpc_byte_buffer_reader reader;

  /* Set up the metadata */
  memset(&meta, 0, sizeof(meta));
  meta.key = "Content-Type";
  meta.value = "application/grpc";
  meta_array.metadata = &meta;
  meta_array.count = 1;

  /* Set up the call */
  call = grpc_server_request_call(context, NULL, &meta_array, NULL);
  if (call == NULL) {
    return;
  }

  /* Send the messages */
  for (int i = 0; i < 10; i++) {
    /* Set up the message */
    response.id = i;
    response.status = STREAMING__PB__MESSAGE_RESPONSE__STATUS__OK;

    /* Set up the buffer */
    buffer = grpc_byte_buffer_create(NULL, 0, NULL);
    grpc_byte_buffer_reader_init(&reader, buffer);

    /* Set up the ops */
    memset(&op, 0, sizeof(op));
    op.op = GRPC_OP_SEND_INITIAL_METADATA;
    op.data.send_initial_metadata.count = 1;
    op.data.send_initial_metadata.metadata = meta_array.metadata;
    ops = &op;

    /* Send the initial metadata */
    call_error = grpc_call_start_batch(call, ops, 1, NULL, NULL);
    if (call_error != GRPC_CALL_OK) {
      return;
    }

    /* Set up the ops */
    memset(&op, 0, sizeof(op));
    op.op = GRPC_OP_SEND_MESSAGE;
    op.data.send_message.send_message = buffer;
    ops = &op;

    /* Send the message */
    call_error = grpc_call_start_batch(call, ops, 1, NULL, NULL);
    if (call_error != GRPC_CALL_OK) {
      return;
    }

    /* Set up the ops */
    memset(&op, 0, sizeof(op));
    op.op = GRPC_OP_SEND_STATUS_FROM_SERVER;
    op.data.send_status_from_server.trailing_metadata_count = 0;
    op.data.send_status_from_server.status = GRPC_STATUS_OK;
    op.data.send_status_from_server.status_details = "";
    ops = &op;

    /* Send the status */
    call_error = grpc_call_start_batch(call, ops, 1, NULL, NULL);
    if (call_error != GRPC_CALL_OK) {
      return;
    }

    /* Sleep for the specified delay */
    sleep(data->delay);
  }

  /* Clean up */
  grpc_call_unref(call);
}

int main(int argc, char **argv) {
  grpc_server *server;
  grpc_server_credentials *creds;
  grpc_completion_queue *cq;
  grpc_event ev;
  pthread_t server_thread;
  server_data data = {0};
  message_data message1 = {1, "Hello, world!", 1};
  message_data message2 = {2, "Goodbye, world!", 2};

  /* Initialize the gRPC library */
  grpc_init();

  /* Create the server */
  cq = grpc_completion_queue_create_for_next(NULL);
  creds = grpc_ssl_server_credentials_create(NULL, NULL);
  server = grpc_server_create(NULL, NULL);
  grpc_server_register_completion_queue(server, cq, NULL);
  grpc_server_add_secure_http2_port(server, SERVER_ADDRESS, creds);
  grpc_ssl_server_credentials_release(creds);

  /* Register the service */
  streaming__pb__add_MessageService__Service(server, NULL, send_messages);

  /* Start the server */
  pthread_create(&server_thread, NULL, run_server, &data);
  data.server = server;

  /* Wait for the server to start */
  ev = grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  if (ev.type != GRPC_OP_COMPLETE) {
    return 1;
  }

  /* Send the messages */
  send_messages(NULL, NULL, &message1);
  send_messages(NULL, NULL, &message2);

  /* Clean up */
  grpc_server_shutdown_and_notify(server, cq, NULL);
  pthread_join(server_thread, NULL);
  grpc_completion_queue_shutdown(cq);
  grpc_completion_queue_destroy(cq);
  grpc_server_destroy(server);
  grpc_shutdown();

  return 0;
}

This example defines a send_messages function that sends a stream of messages to clients using gRPC server streaming. The function takes a streaming__pb__MessageService__Service service, a grpc_server_context context, and a void* argument that contains information about the messages to send. The function uses the gRPC C API to send messages to the client using the grpc_call_start_batch function.

The main function initializes the gRPC library, creates a server, registers a service, and starts the server. It then sends two streams of messages using the send_messages function. Finally, it cleans up the resources used by the server and the gRPC library.

write code gRPC server streaming streaming by C programing language

原文地址: https://www.cveoy.top/t/topic/0A7 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录