源文件
</pre><pre code_snippet_id="1626832" snippet_file_name="blog_20160328_1_7610199" name="code" class="cpp"><pre name="code" class="cpp">#include <string.h>
#include <sys/time.h>
#include <NeptuneClt.h>
#include <unistd.h>
int main()
{
const static int BUFLEN = 256;
NeptuneCltHandle* handle;
int shmid = 787;
char* svc = "Snep_Lookup";
char* command = "Lookup_Lookup";
char url[BUFLEN] = "/view/index.html?name=Jame&age=13";
handle = NeptuneInitClt(stderr, shmid); //Initialize Neptune client handle
printf("init ok\n");
for(int i=0; i<5; i++)
{
unsigned long key = strlen(url) + i;
int partition = key % 3;
size_t nReqlen = strlen(url)+1; // Invoke a request-response call to Neptune module
int fd = NeptuneConnect(handle, svc, partition, Neptune_MODE_READ, command, 0, NULL);
if ( fd < 0 )
{
fprintf(stderr, "NeptuneCall connect failed %d\n", fd);
NeptuneFinalClt(handle);
exit(1);
}
printf("fd:%d partition:%d\n", fd, partition);
int wlen = write(fd, url, nReqlen);
printf("wlen: %d\n", wlen);
char revf[BUFLEN] = {0};
int rlen = read(fd, revf, BUFLEN);
printf("rlen:%d revf: %s\n", rlen, revf);
}
NeptuneFinalClt(handle);
return 0;
}
</pre><pre code_snippet_id="1626832" snippet_file_name="blog_20160328_1_7610199" name="code" class="cpp">
Makefile
</pre><pre code_snippet_id="1626832" snippet_file_name="blog_20160328_1_7610199" name="code" class="cpp"><pre name="code" class="plain">ROOTPATH = ../..
include $(ROOTPATH)/makeincludes/common.inc
include $(ROOTPATH)/makeincludes/path.inc
include $(ROOTPATH)/makeincludes/build.inc
host-type := $(shell uname)
# Global rules
ifeq ($(host-type),Linux)
debug:
$(MAKE) target VARIANT=DBG ARCH=$(host-type)
optimized:
$(MAKE) target VARIANT=OPT ARCH=$(host-type)
else
debug:
$(MAKE) target VARIANT=DBG ARCH=Solaris_v9
optimized:
$(MAKE) target VARIANT=OPT ARCH=Solaris_v9
endif
ifeq ($(VARIANT), DBG)
CCFLAGS += -fprofile-arcs -ftest-coverage
endif
# Macros
SRCS =
OBJS = $(patsubst %.cc,$(OBJDIR)/%.o,$(SRCS))
INCLUDES = -DBUILD_VERSION=\"$(BUILD_VERSION)\" -I$(SHARED_INC) -I$(NEPTUNE_INC) -I../../3rdParty/redisclient/ -I$(XMLCONF_INC)
LIBS = -L$(XMLCONF_LIB) -lxmlconf -L$(SHARED_LIB)/$(TRUEARCH) -lz -DTHREAD=MULTI\
-L$(NEPTUNE_LIB)/$(TRUEARCH) -lNeptuneClt$(SUFFIX) -lutils$(SUFFIX) -lpthread
# -L$(NEPTUNE_LIB)/$(TRUEARCH) -lNeptuneSvc$(SUFFIX) -lutils$(SUFFIX) \
# -lNeptuneClt$(SUFFIX) -L../../3rdParty/redisclient/ -lredisclient\
ifeq ($(VARIANT), DBG)
LIBS += -lgcov
endif
CCFLAGS_COMMON +=
# Local rules
INSTALLDIR = $(REDISPROXY_BIN)
TARGET = ./TClient
target: $(TARGET)
$(TARGET): $(OBJDIR)/.program.dirs $(OBJS) \
$(NEPTUNE_LIB)/$(TRUEARCH)/libNeptuneClt$(SUFFIX).a
$(CC) $(LDFLAGS) -gdb -o $(TARGET) $(OBJS) $(EX_OBJS) $(LIBS)
$(OBJDIR)/.program.dirs:
-mkdir -p $(OBJDIR)
-touch $@
$(OBJDIR)/%.o: %.cc
$(CC) $(CCFLAGS) $(INCLUDES) -o $@ -c $<
@$(CC) $(DEPFLAGS) $(INCLUDES) $< 2>/dev/null | \
sed 's!$*\.o!$(dir $@)&!g' > $(@:.o=.d)
install:
# Clean rule
clean:
-rm -rf $(OBJROOTS) SunWS_cache/
-rm -f *~ *.bak ir.out
-rm -f $(TARGET)
说明一下, neptune节点是个比较轻量的框架,而非类库, 这就意味着,在neptune节点下编写程序的时候,要遵守neptune所提供的范式,实现neptune指定的接口。实现接口这个需要在server端编写,但大致是比较属于固定的套路,按照已有的模板继续实现即可。客户端有request/response和stream两种方式,以上的客户端代码使用了stream流的方式, 思路是建立一个连接,然后在该句柄上进行读写操作,上面的代码先是发送一段模拟的数据,然后等待服务端的回执,服务端根据接受到的句柄,对句柄进行读写,与此类同。总的说来,neptune节点还算是比较简单明了的,不会在框架上做过于复杂的设计。节点本身提供了负载均衡,大部分工作还算要实现自己的项目逻辑。
根据neptune节点的配置,可以推导出其实现策略,各个服务端的代码实现为.so动态链接文件,根据需要动态加载,各个服务使用了共享内存,共享内存的key值需要自己指定,客户端也根据此key值