mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 04:33:05 +00:00
service client and a simple DB example
This commit is contained in:
7
Makefile
7
Makefile
@@ -1,4 +1,4 @@
|
|||||||
all : skynet snlua.so logger.so skynet.so gate.so client skynet-master
|
all : skynet snlua.so logger.so skynet.so gate.so client.so client skynet-master
|
||||||
|
|
||||||
skynet : skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c skynet_server.c skynet_start.c skynet_timer.c skynet_error.c skynet_harbor.c
|
skynet : skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c skynet_server.c skynet_start.c skynet_timer.c skynet_error.c skynet_harbor.c
|
||||||
gcc -Wall -g -Wl,-E -o $@ $^ -lpthread -ldl -lrt -Wl,-E -llua -lm -lzmq
|
gcc -Wall -g -Wl,-E -o $@ $^ -lpthread -ldl -lrt -Wl,-E -llua -lm -lzmq
|
||||||
@@ -15,8 +15,11 @@ gate.so : gate/mread.c gate/ringbuffer.c gate/map.c gate/main.c
|
|||||||
skynet.so : lua-skynet.c
|
skynet.so : lua-skynet.c
|
||||||
gcc -Wall -g -fPIC --shared $^ -o $@
|
gcc -Wall -g -fPIC --shared $^ -o $@
|
||||||
|
|
||||||
|
client.so : service_client.c
|
||||||
|
gcc -Wall -g -fPIC --shared $^ -o $@
|
||||||
|
|
||||||
client : client.c
|
client : client.c
|
||||||
gcc -Wall -g $^ -o $@
|
gcc -Wall -g $^ -o $@ -lpthread
|
||||||
|
|
||||||
skynet-master : master/master.c
|
skynet-master : master/master.c
|
||||||
gcc -g -Wall -o $@ $^ -lzmq
|
gcc -g -Wall -o $@ $^ -lzmq
|
||||||
|
|||||||
17
agent.lua
17
agent.lua
@@ -1,7 +1,16 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
local client = ...
|
||||||
|
|
||||||
print("agent",...)
|
skynet.dispatch(function(msg,session)
|
||||||
|
if session == 0 then
|
||||||
skynet.dispatch(function(msg , addr)
|
print("client command",msg)
|
||||||
print("[agent]",addr,msg)
|
local result = skynet.call("SIMPLEDB",msg)
|
||||||
|
skynet.send(client,0,result)
|
||||||
|
else
|
||||||
|
print("server command",msg)
|
||||||
|
if msg == "CLOSE" then
|
||||||
|
skynet.kill(client)
|
||||||
|
skynet.exit()
|
||||||
|
end
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
47
client.c
47
client.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <pthread.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@@ -7,6 +8,46 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
struct args {
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
readall(int fd, void * buffer, size_t sz) {
|
||||||
|
for (;;) {
|
||||||
|
int err = recv(fd , buffer, sz, MSG_WAITALL);
|
||||||
|
if (err < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
perror("Socket error");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
_read(void *ud) {
|
||||||
|
struct args *p = ud;
|
||||||
|
int fd = p->fd;
|
||||||
|
fflush(stdout);
|
||||||
|
for (;;) {
|
||||||
|
uint8_t header[2];
|
||||||
|
fflush(stdout);
|
||||||
|
readall(fd, header, 2);
|
||||||
|
size_t len = header[0] | header[1] << 8;
|
||||||
|
if (len>0) {
|
||||||
|
char tmp[len+1];
|
||||||
|
readall(fd, tmp, len);
|
||||||
|
tmp[len]='\0';
|
||||||
|
printf("%s\n",tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test(int fd) {
|
test(int fd) {
|
||||||
@@ -50,8 +91,14 @@ main(int argc, char * argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct args arg = { fd };
|
||||||
|
pthread_t pid ;
|
||||||
|
pthread_create(&pid, NULL, _read, &arg);
|
||||||
|
|
||||||
test(fd);
|
test(fd);
|
||||||
|
|
||||||
|
pthread_join(pid, NULL);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
14
gate/main.c
14
gate/main.c
@@ -118,10 +118,16 @@ _report(struct skynet_context * ctx, const char * data, ...) {
|
|||||||
static void
|
static void
|
||||||
_forward(struct skynet_context * ctx,struct gate *g, int uid, void * data, size_t len) {
|
_forward(struct skynet_context * ctx,struct gate *g, int uid, void * data, size_t len) {
|
||||||
struct connection * agent = _id_to_agent(g,uid);
|
struct connection * agent = _id_to_agent(g,uid);
|
||||||
char * tmp = malloc(len + 32);
|
if (agent->agent) {
|
||||||
int n = snprintf(tmp,len+32,"%d data ",uid);
|
char * tmp = malloc(len);
|
||||||
memcpy(tmp+n,data,len);
|
memcpy(tmp,data,len);
|
||||||
skynet_send(ctx, agent->agent ? agent->agent : WATCHDOG, 0, tmp, len + n);
|
skynet_send(ctx, agent->agent, 0, tmp, len);
|
||||||
|
} else {
|
||||||
|
char * tmp = malloc(len + 32);
|
||||||
|
int n = snprintf(tmp,len+32,"%d data ",uid);
|
||||||
|
memcpy(tmp+n,data,len);
|
||||||
|
skynet_send(ctx, WATCHDOG, 0, tmp, len + n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
|
||||||
skynet.dispatch(function(message, from, session)
|
skynet.dispatch(function(message, session , from)
|
||||||
print("[GLOBALLOG]",session, from,message)
|
print("[GLOBALLOG]",session, from,message)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
2
main.lua
2
main.lua
@@ -8,5 +8,7 @@ local watchdog = skynet.launch("snlua","watchdog.lua")
|
|||||||
print("watchdog",watchdog)
|
print("watchdog",watchdog)
|
||||||
local gate = skynet.launch("gate","8888 4 0")
|
local gate = skynet.launch("gate","8888 4 0")
|
||||||
print("gate",gate)
|
print("gate",gate)
|
||||||
|
local db = skynet.launch("snlua","simpledb.lua")
|
||||||
|
print("simpledb",db)
|
||||||
|
|
||||||
skynet.exit()
|
skynet.exit()
|
||||||
|
|||||||
@@ -5,7 +5,4 @@ print("Log server start")
|
|||||||
local log = skynet.launch("snlua","globallog.lua")
|
local log = skynet.launch("snlua","globallog.lua")
|
||||||
print("log",log)
|
print("log",log)
|
||||||
|
|
||||||
local db = skynet.launch("snlua","simpledb.lua")
|
|
||||||
print("simpledb",db)
|
|
||||||
|
|
||||||
skynet.exit()
|
skynet.exit()
|
||||||
|
|||||||
32
service_client.c
Normal file
32
service_client.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include "skynet.h"
|
||||||
|
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb(struct skynet_context * context, void * ud, int session, const char * addr, const void * msg, size_t sz) {
|
||||||
|
assert(session == 0);
|
||||||
|
assert(sz <= 65535);
|
||||||
|
int fd = (int)(intptr_t)ud;
|
||||||
|
|
||||||
|
struct iovec buffer[2];
|
||||||
|
uint8_t head[2] = { sz & 0xff , sz >> 8 & 0xff };
|
||||||
|
buffer[0].iov_base = head;
|
||||||
|
buffer[0].iov_len = 2;
|
||||||
|
buffer[1].iov_base = (void *)msg;
|
||||||
|
buffer[1].iov_len = sz;
|
||||||
|
|
||||||
|
writev(fd, buffer, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
client_init(void * dummy, struct skynet_context *ctx, const char * args) {
|
||||||
|
int fd = strtol(args, NULL, 10);
|
||||||
|
skynet_callback(ctx, (void*)(intptr_t)fd, _cb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -16,7 +16,12 @@ end
|
|||||||
skynet.dispatch(function(message, from, session)
|
skynet.dispatch(function(message, from, session)
|
||||||
print("simpledb",message, from, session)
|
print("simpledb",message, from, session)
|
||||||
local cmd, key , value = string.match(message, "(%w+) (%w+) ?(.*)")
|
local cmd, key , value = string.match(message, "(%w+) (%w+) ?(.*)")
|
||||||
command[cmd](key,value)
|
local f = command[cmd]
|
||||||
|
if f then
|
||||||
|
f(key,value)
|
||||||
|
else
|
||||||
|
skynet.ret("Invalid command : "..message)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
skynet.register "SIMPLEDB"
|
skynet.register "SIMPLEDB"
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ function skynet.exit()
|
|||||||
c.command("EXIT")
|
c.command("EXIT")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function skynet.kill(name)
|
||||||
|
c.command("KILL",name)
|
||||||
|
end
|
||||||
|
|
||||||
skynet.send = c.send
|
skynet.send = c.send
|
||||||
|
|
||||||
function skynet.call(addr, message)
|
function skynet.call(addr, message)
|
||||||
@@ -83,7 +87,7 @@ function skynet.dispatch(f)
|
|||||||
co = coroutine.create(f)
|
co = coroutine.create(f)
|
||||||
session_coroutine_id[co] = session
|
session_coroutine_id[co] = session
|
||||||
session_coroutine_address[co] = address
|
session_coroutine_address[co] = address
|
||||||
suspend(co, coroutine.resume(co, message, address, session))
|
suspend(co, coroutine.resume(co, message, session, address))
|
||||||
else
|
else
|
||||||
session_id_coroutine[session] = nil
|
session_id_coroutine[session] = nil
|
||||||
suspend(co, coroutine.resume(co, message))
|
suspend(co, coroutine.resume(co, message))
|
||||||
|
|||||||
@@ -128,17 +128,20 @@ _dispatch_message(struct skynet_context *ctx, struct skynet_message *msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
_drop_queue(struct message_queue *q) {
|
_drop_queue(struct message_queue *q) {
|
||||||
// todo: send message back to message source
|
// todo: send message back to message source
|
||||||
struct skynet_message msg;
|
struct skynet_message msg;
|
||||||
|
int s = 0;
|
||||||
while(!skynet_mq_pop(q, &msg)) {
|
while(!skynet_mq_pop(q, &msg)) {
|
||||||
|
++s;
|
||||||
if (skynet_harbor_message_isremote(msg.source)) {
|
if (skynet_harbor_message_isremote(msg.source)) {
|
||||||
skynet_harbor_message_close(&msg);
|
skynet_harbor_message_close(&msg);
|
||||||
}
|
}
|
||||||
free(msg.data);
|
free(msg.data);
|
||||||
}
|
}
|
||||||
skynet_mq_release(q);
|
skynet_mq_release(q);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -151,8 +154,10 @@ skynet_context_message_dispatch(void) {
|
|||||||
|
|
||||||
struct skynet_context * ctx = skynet_handle_grab(handle);
|
struct skynet_context * ctx = skynet_handle_grab(handle);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
skynet_error(NULL, "Drop message queue %x ", handle);
|
int s = _drop_queue(q);
|
||||||
_drop_queue(q);
|
if (s>0) {
|
||||||
|
skynet_error(NULL, "Drop message queue %x (%d messages)", handle,s);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,6 +231,21 @@ skynet_command(struct skynet_context * context, const char * cmd , int session,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(cmd,"KILL") == 0) {
|
||||||
|
uint32_t handle = 0;
|
||||||
|
if (parm[0] == ':') {
|
||||||
|
handle = strtoul(parm+1, NULL, 16);
|
||||||
|
} else if (parm[0] == '.') {
|
||||||
|
handle = skynet_handle_findname(parm+1);
|
||||||
|
} else {
|
||||||
|
// todo : kill global service
|
||||||
|
}
|
||||||
|
if (handle) {
|
||||||
|
skynet_handle_retire(handle);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(cmd,"LAUNCH") == 0) {
|
if (strcmp(cmd,"LAUNCH") == 0) {
|
||||||
size_t sz = strlen(parm);
|
size_t sz = strlen(parm);
|
||||||
char tmp[sz+1];
|
char tmp[sz+1];
|
||||||
|
|||||||
15
watchdog.lua
15
watchdog.lua
@@ -1,23 +1,34 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
|
||||||
local command = {}
|
local command = {}
|
||||||
|
local agent_all = {}
|
||||||
|
|
||||||
function command:open(parm)
|
function command:open(parm)
|
||||||
local fd,addr = string.match(parm,"(%d+) ([^%s]+)")
|
local fd,addr = string.match(parm,"(%d+) ([^%s]+)")
|
||||||
fd = tonumber(fd)
|
fd = tonumber(fd)
|
||||||
skynet.send("LOG", 0, string.format("%d %d %s",self,fd,addr))
|
skynet.send("LOG", 0, string.format("%d %d %s",self,fd,addr))
|
||||||
local agent = skynet.launch("snlua","agent.lua",self)
|
local client = skynet.launch("client",fd)
|
||||||
|
print("client",client)
|
||||||
|
local agent = skynet.launch("snlua","agent.lua",client)
|
||||||
if agent then
|
if agent then
|
||||||
|
agent_all[self] = agent
|
||||||
skynet.send("gate",0, "forward ".. self .. " " .. agent)
|
skynet.send("gate",0, "forward ".. self .. " " .. agent)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function command:close()
|
function command:close()
|
||||||
skynet.send("LOG",0,string.format("close %d",self))
|
skynet.send("LOG",0,string.format("close %d",self))
|
||||||
|
skynet.send(agent_all[self],1,"CLOSE")
|
||||||
|
agent_all[self] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function command:data(data)
|
function command:data(data)
|
||||||
skynet.send("LOG",0,string.format("data %d size=%d",self,#data))
|
local agent = agent_all[self]
|
||||||
|
if agent then
|
||||||
|
skynet.send(agent,0,data)
|
||||||
|
else
|
||||||
|
skynet.send("LOG",0,string.format("data %d size=%d",self,#data))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
skynet.dispatch(function(message)
|
skynet.dispatch(function(message)
|
||||||
|
|||||||
Reference in New Issue
Block a user