Recently began to develop on the kendynet, the game type is the survival Challenge class, to store the data structure and types are relatively simple, so chose to use Redis to do storage, data type using string basic is enough. So a simple Redis asynchronous access interface was written on the kendynet.
Design concept
1. Project time is tight, not intended to provide a all-inclusive access interface, only a request interface to issue Redis requests.
2. The key and value are stored as strings in the Redis, and the user is responsible for serializing the data into string and deserializing the data back from string.
3. The service supports local and remote access, and the service automatically returns the results to the requestor based on the location where the request originated.
4. Database operation results are returned to the caller via an asynchronous message
Let's look at a sample usage:
Copy Code code as follows:
#include <stdio.h>
#include <stdlib.h>
#include "Core/msgdisp.h"
#include <stdint.h>
#include "Testcommon.h"
#include "Core/db/asyndb.h"
asyndb_t Asydb;
int g = 0;
int count = 0;
void Db_setcallback (struct db_result *result);
void Db_getcallback (struct db_result *result)
{
printf ("%s\n", result->result_str);
count++;
Char req[256];
snprintf (req,256, "set key%d%d", g,g);
if (0!= asydb->request (asydb,new_dbrequest (Db_set,req,db_setcallback,result->ud,make_by_msgdisp (msgdisp_t )) Result->ud))
printf ("Request error\n");
}
void Db_setcallback (struct db_result *result)
{
if (Result->ud = NULL) printf ("error\n");
Char req[256];
snprintf (req,256, "Get key%d", g);
g = (g+1)%102400;
Asydb->request (Asydb,new_dbrequest) (Db_get,req,db_getcallback,result->ud,make_by_msgdisp (msgdisp_t) Result->ud)));
}
int32_t asynprocesspacket (msgdisp_t disp,msgsender sender,rpacket_t RPK)
{
uint16_t cmd = rpk_read_uint16 (RPK);
if (cmd = = Cmd_db_result)
{
struct Db_result *result = Rpk_read_dbresult (RPK);
Result->callback (result);
Free_dbresult (result);
}
return 1;
}
static void *service_main (void *ud) {
Msgdisp_t disp = (msgdisp_t) UD;
while (!stop) {
Msg_loop (disp,50);
}
return NULL;
}
int main (int argc,char **argv)
{
Setup_signal_handler ();
msgdisp_t DISP1 = New_msgdisp (NULL,
Null
Null
Null
Asynprocesspacket,
NULL);
thread_t Service1 = Create_thread (thread_joinable);
msgdisp_t disp2 = New_msgdisp (NULL,
Null
Null
Null
Asynprocesspacket,
NULL);
thread_t Service2 = Create_thread (thread_joinable);
Asydb = New_asyndb ();
Asydb->connectdb (Asydb, "127.0.0.1", 6379);
Asydb->connectdb (Asydb, "127.0.0.1", 6379);
Issue the first request UU
Char req[256];
snprintf (req,256, "set key%d%d", g,g);
Asydb->request (Asydb,new_dbrequest (Db_set,req,db_setcallback,disp1,make_by_msgdisp (DISP1)));
Thread_start_run (Service1,service_main, (void*) DISP1);
Asydb->request (Asydb,new_dbrequest (Db_set,req,db_setcallback,disp2,make_by_msgdisp (DISP2)));
Thread_start_run (Service2,service_main, (void*) disp2);
uint32_t Tick,now;
Tick = now = Getsystemms ();
while (!stop) {
SLEEPMS (100);
now = Getsystemms ();
if (Now-tick > 1000)
{
printf ("count:%d\n", count);
tick = now;
Count = 0;
}
}
Thread_join (Service1);
Thread_join (SERVICE2);
return 0;
}
The example program above creates a Redis asynchronous processor and then establishes two connections to the same Redis server, in which each connection creates a worker thread, Used to complete the database request. These worker threads share a task queue, and the request sent by the consumer is posted to the task queue, which is extracted and executed by the worker thread.
It then creates two message separators and two threads, then initiates two set requests and initiates message separator threads.
When set returns, the message separator recalls Dbsetcallback and continues to initiate a GET request in Dbsetcallback, which continues to initiate a new set request in the get callback db_getcallback.