├── README.md ├── cpp ├── readme.h ├── run │ ├── restart.sh │ └── run.sh └── src │ ├── base │ ├── BaseSocket.cpp │ ├── BaseSocket.h │ ├── ConfigFileReader.cpp │ ├── ConfigFileReader.h │ ├── EventDispatch.cpp │ ├── EventDispatch.h │ ├── IM.BaseDefine.pb.h │ ├── ImPduBase.cpp │ ├── ImPduBase.h │ ├── ImPduClient.cpp │ ├── ImPduClient.h │ ├── ImPduFile.cpp │ ├── ImPduFile.h │ ├── ImPduGroup.cpp │ ├── ImPduGroup.h │ ├── ImPduServer.cpp │ ├── ImPduServer.h │ ├── Makefile │ ├── ServInfo.cpp │ ├── ServInfo.h │ ├── UtilPdu.cpp │ ├── UtilPdu.h │ ├── imconn.cpp │ ├── imconn.h │ ├── impdu.h │ ├── netlib.cpp │ ├── netlib.h │ ├── ostype.h │ ├── util.cpp │ └── util.h │ ├── build.sh │ ├── file_server │ ├── FileConn.cpp │ ├── FileConn.h │ ├── Makefile │ ├── file_server.cpp │ ├── file_server_util.h │ └── fileserver.conf │ ├── login_server │ ├── LoginConn.cpp │ ├── LoginConn.h │ ├── Makefile │ ├── login_server.cpp │ └── loginserver.conf │ ├── msfs │ ├── HttpConn.cpp │ ├── HttpConn.h │ ├── Makefile │ ├── README │ ├── common │ │ ├── Base64.cpp │ │ ├── BaseSocket.cpp │ │ ├── ConfigFileReader.cpp │ │ ├── EventDispatch.cpp │ │ ├── SimpleBuffer.cpp │ │ ├── StringUtils.cpp │ │ ├── ThreadPool.cpp │ │ ├── jsonxx.cpp │ │ ├── netlib.cpp │ │ └── util.cpp │ ├── http │ │ ├── HttpParser.cpp │ │ └── HttpParserWrapper.cpp │ ├── include │ │ ├── common │ │ │ ├── Base64.h │ │ │ ├── BaseSocket.h │ │ │ ├── ConfigFileReader.h │ │ │ ├── CriticalSection.h │ │ │ ├── EventDispatch.h │ │ │ ├── SimpleBuffer.h │ │ │ ├── StringUtils.h │ │ │ ├── ThreadPool.h │ │ │ ├── atomic.h │ │ │ ├── jsonxx.h │ │ │ ├── netlib.h │ │ │ ├── ostype.h │ │ │ └── util.h │ │ ├── http │ │ │ ├── HttpParser.h │ │ │ └── HttpParserWrapper.h │ │ └── storage │ │ │ ├── FileLin.h │ │ │ ├── FileManager.h │ │ │ └── Portable.h │ ├── main.cpp │ ├── msfs.conf.example │ └── storage │ │ ├── FileLin.cpp │ │ └── FileManager.cpp │ ├── msg_server │ ├── AttachData.cpp │ ├── AttachData.h │ ├── DBServConn.cpp │ ├── DBServConn.h │ ├── FileHandler.cpp │ ├── FileHandler.h │ ├── FileServConn.cpp │ ├── FileServConn.h │ ├── GroupChat.cpp │ ├── GroupChat.h │ ├── HttpConn.cpp │ ├── HttpConn.h │ ├── HttpParserWrapper.cpp │ ├── HttpParserWrapper.h │ ├── HttpQuery.cpp │ ├── HttpQuery.h │ ├── ImUser.cpp │ ├── ImUser.h │ ├── LoginServConn.cpp │ ├── LoginServConn.h │ ├── Makefile │ ├── MsgConn.cpp │ ├── MsgConn.h │ ├── RouteServConn.cpp │ ├── RouteServConn.h │ ├── http_parser.c │ ├── http_parser.h │ ├── jsonxx.cpp │ ├── jsonxx.h │ ├── msg_server.cpp │ ├── msgserv_app.cpp │ ├── msgserv_app.h │ └── msgserver.conf │ ├── route_server │ ├── Makefile │ ├── RouteConn.cpp │ ├── RouteConn.h │ ├── route_server.cpp │ └── routeserver.conf │ └── tools │ ├── Makefile │ └── daeml.cpp ├── docs ├── pics │ └── server.jpg └── protocol │ └── TT_Client_protocol.pdf └── java ├── pom.xml └── src └── main ├── bin ├── packagedev.sh ├── packageproduct.sh ├── run.sh ├── startup.sh └── talkshutdown.sh ├── java └── com │ └── mogujie │ └── ares │ ├── MainServer.java │ ├── configure │ ├── BizConstants.java │ ├── Configure.java │ ├── PBRouter.java │ ├── Router.java │ └── SysConstants.java │ ├── data │ ├── Audio.java │ ├── ClientType.java │ ├── Counter.java │ ├── Department.java │ ├── Group.java │ ├── GroupCounterItem.java │ ├── GroupMessage.java │ ├── GroupRelation.java │ ├── IData.java │ ├── Message.java │ ├── Relationship.java │ ├── TransmitFile.java │ └── User.java │ ├── extend │ ├── ActionContext.java │ ├── ActionHolder.java │ ├── BaseAction.java │ ├── RequestParams.java │ ├── action │ │ ├── Dashboard.java │ │ ├── DelayUpdateMonitor.java │ │ ├── DepartAction.java │ │ ├── FileAction.java │ │ ├── Friendship.java │ │ ├── GroupAction.java │ │ ├── Login.java │ │ ├── MessageContent.java │ │ ├── MessageCounter.java │ │ ├── Monitor.java │ │ ├── ServerConfig.java │ │ ├── StatisticsContent.java │ │ └── UserAction.java │ ├── dispatch │ │ └── DefaultRequestDispatcher.java │ └── filter │ │ ├── IFilter.java │ │ ├── LoginFilter.java │ │ └── MessageContentFilter.java │ ├── lib │ ├── logger │ │ ├── ConnectionKeepAliveFilter.java │ │ ├── Logger.java │ │ ├── LoggerFactory.java │ │ └── NoneFilteredLoggerFilter.java │ ├── net │ │ ├── BinaryMessageHandler.java │ │ ├── DataBuffer.java │ │ ├── FrameBinaryDecoder.java │ │ ├── FrameBinaryEncoder.java │ │ ├── IDispatcher.java │ │ ├── IMHttpResponse.java │ │ ├── MoguHttp.java │ │ ├── MoguHttpResponse.java │ │ └── Packet.java │ └── storage │ │ ├── CachePool.java │ │ └── DBPool.java │ ├── manager │ ├── CacheManager.java │ ├── ConfigureManager.java │ ├── DBManager.java │ ├── ElegantStopManager.java │ ├── FileManager.java │ ├── NetworkManager.java │ └── TimerManager.java │ ├── model │ ├── AudioModel.java │ ├── CounterModel.java │ ├── DepartModel.java │ ├── FileModel.java │ ├── GroupModel.java │ ├── LoginModel.java │ ├── MessageModel.java │ ├── RelationshipModel.java │ ├── ServerConfigModel.java │ ├── StatisticsModel.java │ └── UserModel.java │ ├── timer │ ├── ConfigureReloadTask.java │ ├── Timer.java │ └── WorkerInfoReloader.java │ └── util │ ├── HttpUtil.java │ ├── MoguArrayUtil.java │ ├── MoguByteUtil.java │ └── MoguUtil.java └── resources ├── cache-online.properties ├── common-online.properties ├── db-online.properties ├── logback.xml ├── route.xml ├── system.properties └── timer.xml /README.md: -------------------------------------------------------------------------------- 1 | ###简介: 2 | 3 | TeamTalk是一套开源的企业办公即时通讯软件,作为整套系统的组成部分之一,TTServer为TeamTalk 客户端提供用户登录,消息转发及存储等基础服务。 4 | 5 | TTServer主要包含了以下几种服务器: 6 | 7 | - LoginServer (C++): 登录服务器,分配一个负载小的MsgServer给客户端使用 8 | - MsgServer (C++):  消息服务器,提供客户端大部分信令处理功能,包括私人聊天、群组聊天等 9 | - RouteServer (C++):  路由服务器,为登录在不同MsgServer的用户提供消息转发功能 10 | - FileServer (C++): 文件服务器,提供客户端之间得文件传输服务,支持在线以及离线文件传输 11 | - MsfsServer (C++): 图片存储服务器,提供头像,图片传输中的图片存储服务 12 | - DBProxy (JAVA): 数据库代理服务器,提供mysql以及redis的访问服务,屏蔽其他服务器与mysql与redis的直接交互 13 | 14 | 15 | ###当前支持的功能点: 16 | 17 | - 私人聊天 18 | - 群组聊天 19 | - 文件传输 20 | - 多点登录 21 | - 组织架构设置. 22 | 23 | 24 | ###系统结构图 25 | 26 | ![](https://raw.githubusercontent.com/mogutt/TTServer/master/docs/pics/server.jpg) 27 | 28 | 29 | ###后续可考虑的功能 30 | 31 | - 协议加密 32 | - 手机推送 33 | - 其他合理的酷炫功能点 34 | 35 | 36 | ###C++编译 37 | - 整体编译:可以运行src/目录下的build.sh脚本,例如: ./build.sh version 0.0.1 38 | - 单个模块编译:进入各自的目录,然后执行make即可,注意:base模块需要优先编译 39 | 40 | ###C++使用 41 | - 程序启动请使用run.sh脚本,例如: ./run.sh start 42 | - 程序重启请使用restart.sh脚本,例如: ./restart.sh msg_server 43 | 44 | ###C++部署方案 45 | - 部署方案详见https://github.com/mogutt/TTAutoDeploy 之IM_SERVER模块 46 | 47 | 48 | ###java编译 49 | — 编译整个项目可以运行与src同目录的packageproduct.sh, sh packageproduct.sh 50 | 51 | ###java使用 52 | — 程序启动可以运行与src同目录的startup.sh, sh startup.sh 10400(其中10400为绑定的端口号) 53 | 54 | ###java部署方案 55 | - 部署方案详见https://github.com/mogutt/TTAutoDeploy 之IM_SERVER模块 56 | -------------------------------------------------------------------------------- /cpp/readme.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lizj3624/https-github.com-mogutt-TTServer/46e7665c6a36a577d637830bf04b78862dfd5b75/cpp/readme.h -------------------------------------------------------------------------------- /cpp/run/restart.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | #start or stop the im-server 3 | 4 | function restart() { 5 | cd $1 6 | if [ ! -e *.conf ] 7 | then 8 | echo "no config file" 9 | return 10 | fi 11 | 12 | if [ -e log*_1.txt ]; then 13 | for i in `ls log*_1.txt`; do 14 | pid=`echo $i|awk -F_ '{print $2}'` # get pid 15 | kill -SIGHUP $pid 16 | done 17 | mkdir -p oldlog/ 18 | mv log*.txt oldlog/ 19 | fi 20 | ../daeml ./$1 21 | } 22 | 23 | case $1 in 24 | login_server) 25 | restart $1 26 | ;; 27 | msg_server) 28 | restart $1 29 | ;; 30 | route_server) 31 | restart $1 32 | ;; 33 | file_server) 34 | restart $1 35 | ;; 36 | msfs) 37 | restart $1 38 | ;; 39 | *) 40 | echo "Usage: " 41 | echo " ./restart.sh (login_server|msg_server|route_server|file_server|msfs)" 42 | ;; 43 | esac 44 | -------------------------------------------------------------------------------- /cpp/run/run.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | #start or stop the im-server 3 | 4 | function start() { 5 | cd login_server 6 | if [ -e loginserver.conf ]; then 7 | echo "loginserver.conf exist" 8 | ../daeml ./login_server 9 | fi 10 | 11 | cd ../route_server 12 | if [ -e routeserver.conf ]; then 13 | ../daeml ./route_server 14 | fi 15 | 16 | cd ../msg_server 17 | if [ -e msgserver.conf ]; then 18 | ../daeml ./msg_server 19 | fi 20 | 21 | cd ../file_server 22 | if [ -e fileserver.conf ]; then 23 | ../daeml ./file_server 24 | fi 25 | 26 | cd ../msfs 27 | if [ -e msfs.conf ]; then 28 | ../daeml ./msfs 29 | fi 30 | 31 | cd .. 32 | } 33 | 34 | function stop() { 35 | cd login_server 36 | for i in `ls log*_1.txt`; do 37 | pid=`echo $i|awk -F_ '{print $2}'` # get pid 38 | kill $pid 39 | done 40 | mv log*.txt oldlog/ 41 | 42 | cd ../route_server 43 | for i in `ls log*_1.txt`; do 44 | pid=`echo $i|awk -F_ '{print $2}'` # get pid 45 | kill $pid 46 | done 47 | mv log*.txt oldlog/ 48 | 49 | cd ../msg_server 50 | for i in `ls log*_1.txt`; do 51 | pid=`echo $i|awk -F_ '{print $2}'` # get pid 52 | kill $pid 53 | done 54 | mv log*.txt oldlog/ 55 | 56 | cd ../file_server 57 | for i in `ls log*_1.txt`; do 58 | pid=`echo $i|awk -F_ '{print $2}'` # get pid 59 | kill $pid 60 | done 61 | mv log*.txt oldlog/ 62 | 63 | cd ../msfs 64 | for i in `ls log*_1.txt`; do 65 | pid=`echo $i|awk -F_ '{print $2}'` # get pid 66 | kill $pid 67 | done 68 | mv log*.txt oldlog/ 69 | 70 | cd .. 71 | 72 | } 73 | 74 | case $1 in 75 | start) 76 | start 77 | ;; 78 | stop) 79 | stop 80 | ;; 81 | restart) 82 | stop 83 | start 84 | ;; 85 | *) 86 | echo "Usage: " 87 | echo " ./run.sh (start|stop|restart)" 88 | ;; 89 | esac 90 | -------------------------------------------------------------------------------- /cpp/src/base/BaseSocket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * a wrap for non-block socket class for Windows, LINUX and MacOS X platform 3 | */ 4 | 5 | #ifndef __SOCKET_H__ 6 | #define __SOCKET_H__ 7 | 8 | #include "ostype.h" 9 | #include "util.h" 10 | 11 | enum 12 | { 13 | SOCKET_STATE_IDLE, 14 | SOCKET_STATE_LISTENING, 15 | SOCKET_STATE_CONNECTING, 16 | SOCKET_STATE_CONNECTED, 17 | SOCKET_STATE_CLOSING 18 | }; 19 | 20 | class CBaseSocket : public CRefObject 21 | { 22 | public: 23 | CBaseSocket(); 24 | 25 | virtual ~CBaseSocket(); 26 | 27 | SOCKET GetSocket() { return m_socket; } 28 | void SetSocket(SOCKET fd) { m_socket = fd; } 29 | void SetState(uint8_t state) { m_state = state; } 30 | 31 | void SetCallback(callback_t callback) { m_callback = callback; } 32 | void SetCallbackData(void* data) { m_callback_data = data; } 33 | void SetRemoteIP(char* ip) { m_remote_ip = ip; } 34 | void SetRemotePort(uint16_t port) { m_remote_port = port; } 35 | void SetSendBufSize(uint32_t send_size); 36 | void SetRecvBufSize(uint32_t recv_size); 37 | 38 | const char* GetRemoteIP() { return m_remote_ip.c_str(); } 39 | uint16_t GetRemotePort() { return m_remote_port; } 40 | const char* GetLocalIP() { return m_local_ip.c_str(); } 41 | uint16_t GetLocalPort() { return m_local_port; } 42 | public: 43 | int Listen( 44 | const char* server_ip, 45 | uint16_t port, 46 | callback_t callback, 47 | void* callback_data); 48 | 49 | net_handle_t Connect( 50 | const char* server_ip, 51 | uint16_t port, 52 | callback_t callback, 53 | void* callback_data); 54 | 55 | int Send(void* buf, int len); 56 | 57 | int Recv(void* buf, int len); 58 | 59 | int Close(); 60 | 61 | public: 62 | void OnRead(); 63 | void OnWrite(); 64 | void OnClose(); 65 | 66 | private: 67 | int _GetErrorCode(); 68 | bool _IsBlock(int error_code); 69 | 70 | void _SetNonblock(SOCKET fd); 71 | void _SetReuseAddr(SOCKET fd); 72 | void _SetNoDelay(SOCKET fd); 73 | void _SetAddr(const char* ip, const uint16_t port, sockaddr_in* pAddr); 74 | 75 | void _AcceptNewSocket(); 76 | 77 | private: 78 | string m_remote_ip; 79 | uint16_t m_remote_port; 80 | string m_local_ip; 81 | uint16_t m_local_port; 82 | 83 | callback_t m_callback; 84 | void* m_callback_data; 85 | 86 | uint8_t m_state; 87 | SOCKET m_socket; 88 | }; 89 | 90 | CBaseSocket* FindBaseSocket(net_handle_t fd); 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /cpp/src/base/ConfigFileReader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ConfigFileReader.cpp 3 | * 4 | * Created on: 2013-7-2 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | 9 | #include "ConfigFileReader.h" 10 | 11 | CConfigFileReader::CConfigFileReader(const char* filename) 12 | { 13 | m_config_map = new map; 14 | _LoadFile(filename); 15 | } 16 | 17 | CConfigFileReader::~CConfigFileReader() 18 | { 19 | delete m_config_map; 20 | } 21 | 22 | char* CConfigFileReader::GetConfigName(const char* name) 23 | { 24 | if (!m_load_ok) 25 | return NULL; 26 | 27 | char* value = NULL; 28 | map::iterator it = m_config_map->find(name); 29 | 30 | if(it != m_config_map->end()) 31 | { 32 | value = (char*)it->second.c_str(); 33 | } 34 | 35 | return value; 36 | } 37 | 38 | void CConfigFileReader::_LoadFile(const char* filename) 39 | { 40 | FILE* fp = fopen(filename, "r"); 41 | if (!fp) 42 | { 43 | log("can not open %s\n", filename); 44 | return; 45 | } 46 | 47 | char buf[256]; 48 | for (;;) 49 | { 50 | char* p = fgets(buf, 256, fp); 51 | if (!p) 52 | break; 53 | 54 | size_t len = strlen(buf); 55 | if (buf[len - 1] == '\n') 56 | buf[len - 1] = 0; // remove \n at the end 57 | 58 | char* ch = strchr(buf, '#'); // remove string start with # 59 | if (ch) 60 | *ch = 0; 61 | 62 | if (strlen(buf) == 0) 63 | continue; 64 | 65 | _ParseLine(buf); 66 | } 67 | 68 | fclose(fp); 69 | m_load_ok = true; 70 | } 71 | 72 | void CConfigFileReader::_ParseLine(char* line) 73 | { 74 | char* p = strchr(line, '='); 75 | if (p == NULL) 76 | return; 77 | 78 | *p = 0; 79 | char* key = _TrimSpace(line); 80 | char* value = _TrimSpace(p + 1); 81 | if (key && value) 82 | { 83 | m_config_map->insert(make_pair(key, value)); 84 | } 85 | } 86 | 87 | char* CConfigFileReader::_TrimSpace(char* name) 88 | { 89 | // remove starting space or tab 90 | char* start_pos = name; 91 | while ( (*start_pos == ' ') || (*start_pos == '\t') ) 92 | { 93 | start_pos++; 94 | } 95 | 96 | if (strlen(start_pos) == 0) 97 | return NULL; 98 | 99 | // remove ending space or tab 100 | char* end_pos = name + strlen(name) - 1; 101 | while ( (*end_pos == ' ') || (*end_pos == '\t') ) 102 | { 103 | *end_pos = 0; 104 | end_pos--; 105 | } 106 | 107 | int len = (int)(end_pos - start_pos) + 1; 108 | if (len <= 0) 109 | return NULL; 110 | 111 | return start_pos; 112 | } 113 | -------------------------------------------------------------------------------- /cpp/src/base/ConfigFileReader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ConfigFileReader.h 3 | * 4 | * Created on: 2013-7-2 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef CONFIGFILEREADER_H_ 9 | #define CONFIGFILEREADER_H_ 10 | 11 | #include "util.h" 12 | 13 | class CConfigFileReader 14 | { 15 | public: 16 | CConfigFileReader(const char* filename); 17 | ~CConfigFileReader(); 18 | 19 | char* GetConfigName(const char* name); 20 | private: 21 | void _LoadFile(const char* filename); 22 | void _ParseLine(char* line); 23 | char* _TrimSpace(char* name); 24 | 25 | bool m_load_ok; 26 | map* m_config_map; 27 | }; 28 | 29 | 30 | 31 | #endif /* CONFIGFILEREADER_H_ */ 32 | -------------------------------------------------------------------------------- /cpp/src/base/EventDispatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A socket event dispatcher, features include: 3 | * 1. portable: worked both on Windows, MAC OS X, LINUX platform 4 | * 2. a singleton pattern: only one instance of this class can exist 5 | */ 6 | #ifndef __EVENT_DISPATCH_H__ 7 | #define __EVENT_DISPATCH_H__ 8 | 9 | #include "ostype.h" 10 | #include "util.h" 11 | 12 | enum { 13 | SOCKET_READ = 0x1, 14 | SOCKET_WRITE = 0x2, 15 | SOCKET_EXCEP = 0x4, 16 | SOCKET_ALL = 0x7 17 | }; 18 | 19 | class CEventDispatch 20 | { 21 | public: 22 | virtual ~CEventDispatch(); 23 | 24 | void AddEvent(SOCKET fd, uint8_t socket_event); 25 | void RemoveEvent(SOCKET fd, uint8_t socket_event); 26 | 27 | void AddTimer(callback_t callback, void* user_data, uint64_t interval); 28 | void RemoveTimer(callback_t callback, void* user_data); 29 | 30 | void StartDispatch(); 31 | 32 | static CEventDispatch* Instance(); 33 | protected: 34 | CEventDispatch(); 35 | 36 | private: 37 | void _CheckTimer(); 38 | 39 | typedef struct { 40 | callback_t callback; 41 | void* user_data; 42 | uint64_t interval; 43 | uint64_t next_tick; 44 | } TimerItem; 45 | 46 | private: 47 | #ifdef _WIN32 48 | fd_set m_read_set; 49 | fd_set m_write_set; 50 | fd_set m_excep_set; 51 | #elif __APPLE__ 52 | int m_kqfd; 53 | #else 54 | int m_epfd; 55 | #endif 56 | CThreadLock m_lock; 57 | list m_timer_list; 58 | 59 | static CEventDispatch* m_pEventDispatch; 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /cpp/src/base/Makefile: -------------------------------------------------------------------------------- 1 | LIBBASE = libbase.a 2 | 3 | COMMON_PATH := ./ 4 | SRCDIRS := ./ 5 | CPPFLAGS += -fPIC -I$(COMMON_PATH) 6 | CPPFLAGS += -Wall -Wno-deprecated -g 7 | 8 | SRCEXTS := .c .cpp 9 | CC = g++ 10 | SHELL = /bin/sh 11 | SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS)))) 12 | OBJS= $(patsubst %.cpp,./obj/%.o,$(notdir $(SOURCES))) 13 | GCNOS= $(patsubst %.cpp,./obj/%.gcno,$(notdir $(SOURCES))) 14 | 15 | all: $(LIBBASE) 16 | 17 | $(LIBBASE): $(OBJS) 18 | ar -r $@ $(OBJS) 19 | 20 | objs : $(OBJS) 21 | ./obj/%.o : %.c 22 | gcc -c $(CPPFLAGS) $(CFLAGS) $< -o $(patsubst %.c,%.o, $<) 23 | ./obj/%.o : %.cpp 24 | @mkdir -p $(dir $@) 25 | @echo "==================" 26 | @echo "Compiling $<" 27 | $(CC) -c $(CPPFLAGS) $< -o $@ 28 | 29 | .PHONY : clean 30 | clean: 31 | rm -f $(OBJS) 32 | rm -f $(LIBBASE) 33 | -------------------------------------------------------------------------------- /cpp/src/base/ServInfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ServInfo.cpp 3 | * 4 | * Created on: 2013-8-8 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #include "ServInfo.h" 9 | 10 | serv_info_t* read_server_config(CConfigFileReader* config_file, const char* server_ip_format, 11 | const char* server_port_format, uint32_t& server_count) 12 | { 13 | char server_ip_key[64]; 14 | char server_port_key[64]; 15 | 16 | server_count = 0; 17 | 18 | // get server_count first; 19 | while (true) { 20 | sprintf(server_ip_key, "%s%d", server_ip_format, server_count + 1); 21 | sprintf(server_port_key, "%s%d", server_port_format, server_count + 1); 22 | char* server_ip_value = config_file->GetConfigName(server_ip_key); 23 | char* server_port_value = config_file->GetConfigName(server_port_key); 24 | if (!server_ip_value || !server_port_value) { 25 | break; 26 | } 27 | 28 | server_count++; 29 | } 30 | 31 | if (server_count == 0) { 32 | return NULL; 33 | } 34 | 35 | serv_info_t* server_list = new serv_info_t [server_count]; 36 | 37 | for (uint32_t i = 0; i < server_count; i++) { 38 | sprintf(server_ip_key, "%s%d", server_ip_format, i + 1); 39 | sprintf(server_port_key, "%s%d", server_port_format, i + 1); 40 | char* server_ip_value = config_file->GetConfigName(server_ip_key); 41 | char* server_port_value = config_file->GetConfigName(server_port_key); 42 | server_list[i].server_ip = server_ip_value; 43 | server_list[i].server_port = atoi(server_port_value); 44 | } 45 | 46 | return server_list; 47 | } 48 | -------------------------------------------------------------------------------- /cpp/src/base/ServInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ServInfo.h 3 | * 4 | * Created on: 2013-7-19 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef SERVINFO_H_ 9 | #define SERVINFO_H_ 10 | 11 | #include "util.h" 12 | #include "imconn.h" 13 | #include "ConfigFileReader.h" 14 | 15 | #define MAX_RECONNECT_CNT 64 16 | #define MIN_RECONNECT_CNT 4 17 | 18 | typedef struct { 19 | string server_ip; 20 | uint16_t server_port; 21 | uint32_t idle_cnt; 22 | uint32_t reconnect_cnt; 23 | CImConn* serv_conn; 24 | } serv_info_t; 25 | 26 | template 27 | void serv_init(serv_info_t* server_list, uint32_t server_count) 28 | { 29 | for (uint32_t i = 0; i < server_count; i++) { 30 | T* pConn = new T(); 31 | pConn->Connect(server_list[i].server_ip.c_str(), server_list[i].server_port, i); 32 | server_list[i].serv_conn = pConn; 33 | server_list[i].idle_cnt = 0; 34 | server_list[i].reconnect_cnt = MIN_RECONNECT_CNT / 2; 35 | } 36 | } 37 | 38 | template 39 | void serv_check_reconnect(serv_info_t* server_list, uint32_t server_count) 40 | { 41 | T* pConn; 42 | for (uint32_t i = 0; i < server_count; i++) { 43 | pConn = (T*)server_list[i].serv_conn; 44 | if (!pConn) { 45 | server_list[i].idle_cnt++; 46 | if (server_list[i].idle_cnt >= server_list[i].reconnect_cnt) { 47 | pConn = new T(); 48 | pConn->Connect(server_list[i].server_ip.c_str(), server_list[i].server_port, i); 49 | server_list[i].serv_conn = pConn; 50 | } 51 | } 52 | } 53 | } 54 | 55 | template 56 | void serv_reset(serv_info_t* server_list, uint32_t server_count, uint32_t serv_idx) 57 | { 58 | if (serv_idx >= server_count) { 59 | return; 60 | } 61 | 62 | server_list[serv_idx].serv_conn = NULL; 63 | server_list[serv_idx].idle_cnt = 0; 64 | server_list[serv_idx].reconnect_cnt *= 2; 65 | if (server_list[serv_idx].reconnect_cnt > MAX_RECONNECT_CNT) { 66 | server_list[serv_idx].reconnect_cnt = MIN_RECONNECT_CNT; 67 | } 68 | } 69 | 70 | serv_info_t* read_server_config(CConfigFileReader* config_file, const char* server_ip_format, 71 | const char* server_port_format, uint32_t& server_count); 72 | 73 | 74 | #endif /* SERVINFO_H_ */ 75 | -------------------------------------------------------------------------------- /cpp/src/base/UtilPdu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * UtilPdu.h 3 | * 4 | * Created on: 2013-8-27 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef UTILPDU_H_ 9 | #define UTILPDU_H_ 10 | 11 | #include "ostype.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #ifdef WIN32 19 | #ifdef BUILD_PDU 20 | #define DLL_MODIFIER __declspec(dllexport) 21 | #else 22 | #define DLL_MODIFIER __declspec(dllimport) 23 | #endif 24 | #else 25 | #define DLL_MODIFIER 26 | #endif 27 | 28 | class DLL_MODIFIER CSimpleBuffer 29 | { 30 | public: 31 | CSimpleBuffer(); 32 | ~CSimpleBuffer(); 33 | uchar_t* GetBuffer() { return m_buffer; } 34 | uint32_t GetAllocSize() { return m_alloc_size; } 35 | uint32_t GetWriteOffset() { return m_write_offset; } 36 | void IncWriteOffset(uint32_t len) { m_write_offset += len; } 37 | 38 | void Extend(uint32_t len); 39 | uint32_t Write(void* buf, uint32_t len); 40 | uint32_t Read(void* buf, uint32_t len); 41 | private: 42 | uchar_t* m_buffer; 43 | uint32_t m_alloc_size; 44 | uint32_t m_write_offset; 45 | }; 46 | 47 | class CByteStream 48 | { 49 | public: 50 | CByteStream(uchar_t* buf, uint32_t len); 51 | CByteStream(CSimpleBuffer* pSimpBuf, uint32_t pos); 52 | ~CByteStream() {} 53 | 54 | unsigned char* GetBuf() { return m_pSimpBuf ? m_pSimpBuf->GetBuffer() : m_pBuf; } 55 | uint32_t GetPos() { return m_pos; } 56 | uint32_t GetLen() { return m_len; } 57 | void Skip(uint32_t len) { m_pos += len; } 58 | 59 | static int16_t ReadInt16(uchar_t* buf); 60 | static uint16_t ReadUint16(uchar_t* buf); 61 | static int32_t ReadInt32(uchar_t* buf); 62 | static uint32_t ReadUint32(uchar_t* buf); 63 | static void WriteInt16(uchar_t* buf, int16_t data); 64 | static void WriteUint16(uchar_t* buf, uint16_t data); 65 | static void WriteInt32(uchar_t* buf, int32_t data); 66 | static void WriteUint32(uchar_t* buf, uint32_t data); 67 | 68 | void operator << (int8_t data); 69 | void operator << (uint8_t data); 70 | void operator << (int16_t data); 71 | void operator << (uint16_t data); 72 | void operator << (int32_t data); 73 | void operator << (uint32_t data); 74 | 75 | void operator >> (int8_t& data); 76 | void operator >> (uint8_t& data); 77 | void operator >> (int16_t& data); 78 | void operator >> (uint16_t& data); 79 | void operator >> (int32_t& data); 80 | void operator >> (uint32_t& data); 81 | 82 | void WriteString(const char* str); 83 | void WriteString(const char* str, uint32_t len); 84 | char* ReadString(uint32_t& len); 85 | 86 | void WriteData(uchar_t* data, uint32_t len); 87 | uchar_t* ReadData(uint32_t& len); 88 | private: 89 | void _WriteByte(void* buf, uint32_t len); 90 | void _ReadByte(void* buf, uint32_t len); 91 | private: 92 | CSimpleBuffer* m_pSimpBuf; 93 | uchar_t* m_pBuf; 94 | uint32_t m_len; 95 | uint32_t m_pos; 96 | }; 97 | 98 | #define ERROR_CODE_PARSE_FAILED 1 99 | #define ERROR_CODE_WRONG_SERVICE_ID 2 100 | #define ERROR_CODE_WRONG_COMMAND_ID 3 101 | #define ERROR_CODE_ALLOC_FAILED 4 102 | 103 | class CPduException { 104 | public: 105 | CPduException(uint32_t module_id, uint32_t command_id, uint32_t error_code, const char* error_msg) 106 | { 107 | m_module_id = module_id; 108 | m_command_id = command_id; 109 | m_error_code = error_code; 110 | m_error_msg = error_msg; 111 | } 112 | 113 | virtual ~CPduException() {} 114 | 115 | uint32_t GetModuleId() { return m_module_id; } 116 | uint32_t GetCommandId() { return m_command_id; } 117 | uint32_t GetErrorCode() { return m_error_code; } 118 | char* GetErrorMsg() { return (char*)m_error_msg.c_str(); } 119 | private: 120 | uint32_t m_module_id; 121 | uint32_t m_command_id; 122 | uint32_t m_error_code; 123 | string m_error_msg; 124 | }; 125 | 126 | char* idtourl(uint32_t id); 127 | uint32_t urltoid(const char* url); 128 | 129 | 130 | #endif /* UTILPDU_H_ */ 131 | -------------------------------------------------------------------------------- /cpp/src/base/imconn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * imconn.h 3 | * 4 | * Created on: 2013-6-5 5 | * Author: ziteng 6 | */ 7 | 8 | #ifndef IMCONN_H_ 9 | #define IMCONN_H_ 10 | 11 | #include "netlib.h" 12 | #include "util.h" 13 | #include "impdu.h" 14 | 15 | #define SERVER_HEARTBEAT_INTERVAL 5000 16 | #define SERVER_TIMEOUT 30000 17 | #define CLIENT_HEARTBEAT_INTERVAL 5000 18 | #define CLIENT_TIMEOUT 30000 19 | #define MOBILE_CLIENT_TIMEOUT 30000 * 10 20 | #define READ_BUF_SIZE 2048 21 | 22 | class CImConn : public CRefObject 23 | { 24 | public: 25 | CImConn(); 26 | virtual ~CImConn(); 27 | 28 | bool IsBusy() { return m_busy; } 29 | int SendPdu(CImPdu* pPdu) { return Send(pPdu->GetBuffer(), pPdu->GetLength()); } 30 | int Send(void* data, int len); 31 | 32 | virtual void OnConnect(net_handle_t handle) { m_handle = handle; } 33 | virtual void OnConfirm() {} 34 | virtual void OnRead(); 35 | virtual void OnWrite(); 36 | virtual void OnClose() {} 37 | virtual void OnTimer(uint64_t curr_tick) {} 38 | 39 | virtual void HandlePdu(CImPdu* pPdu) {} 40 | 41 | protected: 42 | net_handle_t m_handle; 43 | bool m_busy; 44 | 45 | string m_peer_ip; 46 | uint16_t m_peer_port; 47 | CSimpleBuffer m_in_buf; 48 | CSimpleBuffer m_out_buf; 49 | 50 | bool m_policy_conn; 51 | uint32_t m_recv_bytes; 52 | uint64_t m_last_send_tick; 53 | uint64_t m_last_recv_tick; 54 | }; 55 | 56 | typedef hash_map ConnMap_t; 57 | typedef hash_map UserMap_t; 58 | typedef hash_map UserConnCntMap_t; 59 | 60 | void imconn_callback(void* callback_data, uint8_t msg, uint32_t handle, void* pParam); 61 | 62 | #endif /* IMCONN_H_ */ 63 | -------------------------------------------------------------------------------- /cpp/src/base/impdu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * impdu.h 3 | * 4 | * packet data unit, packet encapsulation and parse 5 | * Created on: 2013-6-8 6 | * Author: ziteng@mogujie.com 7 | */ 8 | 9 | #ifndef IMPDU_H_ 10 | #define IMPDU_H_ 11 | 12 | 13 | #include "ImPduBase.h" 14 | #include "ImPduClient.h" 15 | #include "ImPduServer.h" 16 | #include "ImPduFile.h" 17 | #include "ImPduGroup.h" 18 | 19 | #endif /* IMPDU_H_ */ 20 | -------------------------------------------------------------------------------- /cpp/src/base/netlib.h: -------------------------------------------------------------------------------- 1 | #ifndef __NETLIB_H__ 2 | #define __NETLIB_H__ 3 | 4 | #include "ostype.h" 5 | 6 | #define NETLIB_OPT_SET_CALLBACK 1 7 | #define NETLIB_OPT_SET_CALLBACK_DATA 2 8 | #define NETLIB_OPT_GET_REMOTE_IP 3 9 | #define NETLIB_OPT_GET_REMOTE_PORT 4 10 | #define NETLIB_OPT_GET_LOCAL_IP 5 11 | #define NETLIB_OPT_GET_LOCAL_PORT 6 12 | #define NETLIB_OPT_SET_SEND_BUF_SIZE 7 13 | #define NETLIB_OPT_SET_RECV_BUF_SIZE 8 14 | 15 | #define NETLIB_MAX_SOCKET_BUF_SIZE (128 * 1024) 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | int netlib_init(); 22 | 23 | int netlib_destroy(); 24 | 25 | int netlib_listen( 26 | const char* server_ip, 27 | uint16_t port, 28 | callback_t callback, 29 | void* callback_data); 30 | 31 | net_handle_t netlib_connect( 32 | const char* server_ip, 33 | uint16_t port, 34 | callback_t callback, 35 | void* callback_data); 36 | 37 | int netlib_send(net_handle_t handle, void* buf, int len); 38 | 39 | int netlib_recv(net_handle_t handle, void* buf, int len); 40 | 41 | int netlib_close(net_handle_t handle); 42 | 43 | int netlib_option(net_handle_t handle, int opt, void* optval); 44 | 45 | int netlib_register_timer(callback_t callback, void* user_data, uint64_t interval); 46 | 47 | int netlib_delete_timer(callback_t callback, void* user_data); 48 | 49 | void netlib_eventloop(); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /cpp/src/base/ostype.h: -------------------------------------------------------------------------------- 1 | // OS dependant type definition 2 | #ifndef __OS_TYPE_H__ 3 | #define __OS_TYPE_H__ 4 | 5 | #ifdef _WIN32 6 | #include 7 | #include 8 | #else 9 | #ifdef __APPLE__ 10 | #include 11 | #include 12 | #include // syscall(SYS_gettid) 13 | #else 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include // define int8_t ... 28 | #include 29 | #define closesocket close 30 | #define ioctlsocket ioctl 31 | #endif 32 | 33 | #ifdef _WIN32 34 | #if (_MSC_VER >= 1800) 35 | //vs2013+ 36 | #include 37 | #else 38 | typedef char int8_t; 39 | typedef short int16_t; 40 | typedef int int32_t; 41 | typedef long long int64_t; 42 | typedef unsigned char uint8_t; 43 | typedef unsigned short uint16_t; 44 | typedef unsigned int uint32_t; 45 | typedef unsigned long long uint64_t; 46 | #endif 47 | typedef int socklen_t; 48 | #else 49 | typedef int SOCKET; 50 | typedef int BOOL; 51 | const int TRUE = 1; 52 | const int FALSE = 0; 53 | const int SOCKET_ERROR = -1; 54 | const int INVALID_SOCKET = -1; 55 | #endif 56 | 57 | typedef unsigned char uchar_t; 58 | typedef int net_handle_t; 59 | typedef int conn_handle_t; 60 | 61 | enum { 62 | NETLIB_OK = 0, 63 | NETLIB_ERROR = -1 64 | }; 65 | 66 | #define NETLIB_INVALID_HANDLE -1 67 | 68 | enum 69 | { 70 | NETLIB_MSG_CONNECT = 1, 71 | NETLIB_MSG_CONFIRM, 72 | NETLIB_MSG_READ, 73 | NETLIB_MSG_WRITE, 74 | NETLIB_MSG_CLOSE, 75 | NETLIB_MSG_TIMER 76 | }; 77 | 78 | typedef void (*callback_t)(void* callback_data, uint8_t msg, uint32_t handle, void* pParam); 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /cpp/src/base/util.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTIL_H__ 2 | #define __UTIL_H__ 3 | 4 | #define _CRT_SECURE_NO_DEPRECATE // remove warning C4996, 5 | 6 | #include "ostype.h" 7 | #include "UtilPdu.h" 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef _WIN32 13 | #define snprintf sprintf_s 14 | #else 15 | #include 16 | #include 17 | #include 18 | #include 19 | #endif 20 | 21 | #ifdef _WIN32 22 | #include 23 | using namespace stdext; 24 | #else 25 | #include 26 | using namespace __gnu_cxx; 27 | #endif 28 | 29 | #define MAX_LOG_FILE_SIZE 0x4000000 // 64MB 30 | #define NOTUSED_ARG(v) ((void)v) // used this to remove warning C4100, unreferenced parameter 31 | 32 | class CThread 33 | { 34 | public: 35 | CThread(); 36 | virtual ~CThread(); 37 | 38 | #ifdef _WIN32 39 | static DWORD WINAPI StartRoutine(LPVOID arg); 40 | #else 41 | static void* StartRoutine(void* arg); 42 | #endif 43 | 44 | virtual void StartThread(void); 45 | virtual void OnThreadRun(void) = 0; 46 | protected: 47 | #ifdef _WIN32 48 | DWORD m_thread_id; 49 | #else 50 | pthread_t m_thread_id; 51 | #endif 52 | }; 53 | 54 | class CEventThread : public CThread 55 | { 56 | public: 57 | CEventThread(); 58 | virtual ~CEventThread(); 59 | 60 | virtual void OnThreadTick(void) = 0; 61 | virtual void OnThreadRun(void); 62 | virtual void StartThread(); 63 | virtual void StopThread(); 64 | bool IsRunning() { return m_bRunning; } 65 | private: 66 | bool m_bRunning; 67 | }; 68 | 69 | class CThreadLock 70 | { 71 | public: 72 | CThreadLock(); 73 | ~CThreadLock(); 74 | void Lock(void); 75 | void Unlock(void); 76 | private: 77 | #ifdef _WIN32 78 | CRITICAL_SECTION m_critical_section; 79 | #else 80 | pthread_mutex_t m_mutex; 81 | pthread_mutexattr_t m_mutexattr; 82 | #endif 83 | }; 84 | 85 | class CFuncLock 86 | { 87 | public: 88 | CFuncLock(CThreadLock* lock) 89 | { 90 | m_lock = lock; 91 | if (m_lock) 92 | m_lock->Lock(); 93 | } 94 | 95 | ~CFuncLock() 96 | { 97 | if (m_lock) 98 | m_lock->Unlock(); 99 | } 100 | private: 101 | CThreadLock* m_lock; 102 | }; 103 | 104 | class CRefObject 105 | { 106 | public: 107 | CRefObject(); 108 | virtual ~CRefObject(); 109 | 110 | void SetLock(CThreadLock* lock) { m_lock = lock; } 111 | void AddRef(); 112 | void ReleaseRef(); 113 | private: 114 | int m_refCount; 115 | CThreadLock* m_lock; 116 | }; 117 | 118 | /// yunfan modify 2014.8.12 119 | #if defined(_WIN32) || defined(_WIN64) 120 | #define log(fmt, ...) logger("<%s>\t<%d>\t<%s>,"fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 121 | #else 122 | #define log(fmt, args...) logger("<%s>|<%d>|<%s>," fmt, __FILE__, __LINE__, __FUNCTION__, ##args) 123 | #endif 124 | void logger(const char* fmt, ...); 125 | /// yunfan modify end 126 | 127 | uint64_t get_tick_count(); 128 | void util_sleep(uint32_t millisecond); 129 | 130 | class CStrExplode 131 | { 132 | public: 133 | CStrExplode(char* str, char seperator); 134 | virtual ~CStrExplode(); 135 | 136 | uint32_t GetItemCnt() { return m_item_cnt; } 137 | char* GetItem(uint32_t idx) { return m_item_list[idx]; } 138 | private: 139 | uint32_t m_item_cnt; 140 | char** m_item_list; 141 | }; 142 | #endif 143 | -------------------------------------------------------------------------------- /cpp/src/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | build() { 4 | echo "#ifndef __VERSION_H__" > base/version.h 5 | echo "#define __VERSION_H__" >> base/version.h 6 | echo "#define VERSION \"$1\"" >> base/version.h 7 | echo "#endif" >> base/version.h 8 | 9 | cd base 10 | make 11 | cd ../login_server 12 | make 13 | cd ../route_server 14 | make 15 | cd ../msg_server 16 | make 17 | cd ../file_server 18 | make 19 | cd ../msfs 20 | make 21 | cd ../tools 22 | make 23 | cd ../ 24 | 25 | mkdir -p ../run/login_server 26 | mkdir -p ../run/route_server 27 | mkdir -p ../run/msg_server 28 | mkdir -p ../run/file_server 29 | mkdir -p ../run/msfs 30 | #copy executables to run/ dir 31 | 32 | 33 | cp login_server/login_server ../run/login_server/ 34 | cp route_server/route_server ../run/route_server/ 35 | cp msg_server/msg_server ../run/msg_server/ 36 | cp file_server/file_server ../run/file_server/ 37 | cp msfs/msfs ../run/msfs/ 38 | cp tools/daeml ../run/ 39 | 40 | build_version=im-server-$1 41 | build_name=$build_version.tar.gz 42 | if [ -e "$build_name" ]; then 43 | rm $build_name 44 | fi 45 | 46 | mkdir -p ../$build_version 47 | mkdir -p ../$build_version/login_server 48 | mkdir -p ../$build_version/route_server 49 | mkdir -p ../$build_version/msg_server 50 | mkdir -p ../$build_version/file_server 51 | mkdir -p ../$build_version/msfs 52 | cp login_server/login_server ../$build_version/login_server/ 53 | cp login_server/loginserver.conf ../$build_version/login_server/ 54 | cp route_server/route_server ../$build_version/route_server/ 55 | cp route_server/routeserver.conf ../$build_version/route_server/ 56 | cp msg_server/msg_server ../$build_version/msg_server/ 57 | cp msg_server/msgserver.conf ../$build_version/msg_server/ 58 | cp file_server/file_server ../$build_version/file_server/ 59 | cp file_server/fileserver.conf ../$build_version/file_server/ 60 | cp msfs/msfs ../$build_version/msfs/ 61 | cp msfs/msfs.conf.example ../$build_version/msfs/msfs.conf 62 | cp tools/daeml ../$build_version/ 63 | cp ../run/restart.sh ../$build_version/ 64 | cp ../run/run.sh ../$build_version/ 65 | 66 | cd ../ 67 | tar zcvf $build_name $build_version/daeml $build_version/restart.sh $build_version/run.sh \ 68 | $build_version/login_server/login_server $build_version/login_server/loginserver.conf \ 69 | $build_version/route_server/route_server $build_version/route_server/routeserver.conf \ 70 | $build_version/msg_server/msg_server $build_version/msg_server/msgserver.conf\ 71 | $build_version/file_server/file_server $build_version/file_server/fileserver.conf\ 72 | $build_version/msfs/msfs $build_version/msfs/msfs.conf 73 | rm -rf $build_version 74 | } 75 | 76 | clean() { 77 | cd base 78 | make clean 79 | cd ../login_server 80 | make clean 81 | cd ../route_server 82 | make clean 83 | cd ../msg_server 84 | make clean 85 | cd ../file_server 86 | make clean 87 | cd ../msfs 88 | make clean 89 | 90 | } 91 | 92 | print_help() { 93 | echo "Usage: " 94 | echo " $0 clean --- clean all build" 95 | echo " $0 version version_str --- build a version" 96 | } 97 | 98 | case $1 in 99 | clean) 100 | echo "clean all build..." 101 | clean 102 | ;; 103 | version) 104 | if [ $# != 2 ]; then 105 | echo $# 106 | print_help 107 | exit 108 | fi 109 | 110 | echo $2 111 | echo "build..." 112 | build $2 113 | ;; 114 | *) 115 | print_help 116 | ;; 117 | esac 118 | -------------------------------------------------------------------------------- /cpp/src/file_server/FileConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FileConn.h 3 | * 4 | * Created on: 2013-12-9 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef FILECONN_H_ 9 | #define FILECONN_H_ 10 | 11 | #include "imconn.h" 12 | #include "impdu.h" 13 | #include 14 | #include 15 | #include 16 | #include "file_server_util.h" 17 | 18 | 19 | typedef struct { 20 | FILE* fp; 21 | string file_path; 22 | string save_path; 23 | string peer_user_id; 24 | uint32_t file_size; 25 | uint32_t transfer_size; 26 | } file_stat_t; 27 | 28 | 29 | typedef map FileMap_t; 30 | 31 | /// yunfan add 2014.8.6 32 | 33 | 34 | typedef map TaskMap_t; // on client connect 35 | /// yunfan add end 36 | 37 | class CFileConn : public CImConn 38 | { 39 | public: 40 | CFileConn(); 41 | virtual ~CFileConn(); 42 | 43 | virtual void Close(); 44 | 45 | void OnConnect(net_handle_t handle); 46 | virtual void OnClose(); 47 | virtual void OnTimer(uint64_t curr_tick); 48 | 49 | virtual void OnWrite(); 50 | virtual void HandlePdu(CImPdu* pPdu); 51 | 52 | private: 53 | int _HandleClientFileLoginReq(CImPduClientFileLoginReq* pPdu); 54 | 55 | /// yunfan add 2014.8.6 56 | int _HandleMsgFileTransferReq(CImPduMsgFileTransferReq* pPdu); 57 | int _HandleClientFileStates(CImPduClientFileState* pPdu); 58 | int _HandleClientFilePullFileReq(CImPduClientFilePullDataReq* pPdu); 59 | int _HandleClientFilePullFileRsp(CImPduClientFilePullDataRsp *pPdu); 60 | int _StatesNotify(int state, const char* task_id, uint32_t user_id, CImConn* pConn); 61 | int _HandleGetServerAddressReq(CImPduFileServerIPReq* pPdu); 62 | /// yunfan add end 63 | 64 | bool _IsAuth() { return m_bAuth; } 65 | 66 | /// yunfan add 2014.8.18 67 | private: 68 | int _PreUpload(const char* task_id); 69 | // int _DoUpload(const char* task_id); 70 | /// yunan add end 71 | 72 | 73 | private: 74 | bool m_bAuth; 75 | uint32_t m_user_id; 76 | string m_user_id_url; 77 | FileMap_t m_save_file_map; 78 | TaskMap_t m_file_task_map; 79 | list m_send_file_list; 80 | 81 | /// yunfan add 2014.8.7 82 | std::deque m_filedatad_queue; 83 | /// yunfan add end 84 | }; 85 | 86 | void init_file_conn(std::list&, uint32_t timeout); 87 | 88 | #endif /* FILECONN_H_ */ 89 | -------------------------------------------------------------------------------- /cpp/src/file_server/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INC = ../base 4 | OPT = -Wall -Wno-deprecated -g 5 | 6 | OBJS = FileConn.o file_server.o ../base/libbase.a 7 | 8 | OS_NAME = $(shell uname) 9 | LC_OS_NAME = $(shell echo $(OS_NAME) | tr '[A-Z]' '[a-z]') 10 | ifeq ($(LC_OS_NAME), darwin) 11 | LIBS = -lpthread 12 | else 13 | LIBS = -lpthread -luuid 14 | endif 15 | 16 | 17 | SERVER = file_server 18 | 19 | all: $(SERVER) 20 | 21 | $(SERVER): $(OBJS) 22 | $(CC) $(OPT) -o $@ $(OBJS) $(LIBS) 23 | 24 | FileConn.o: FileConn.cpp 25 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 26 | 27 | file_server.o: file_server.cpp 28 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 29 | 30 | clean: 31 | rm -f $(SERVER) *.o 32 | 33 | -------------------------------------------------------------------------------- /cpp/src/file_server/file_server.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * file_server.cpp 3 | * 4 | * Created on: 2013-12-9 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #include "FileConn.h" 9 | #include "netlib.h" 10 | #include "ConfigFileReader.h" 11 | #include "version.h" 12 | 13 | void file_serv_callback(void* callback_data, uint8_t msg, uint32_t handle, void* pParam) 14 | { 15 | if (msg == NETLIB_MSG_CONNECT) { 16 | CFileConn* pConn = new CFileConn(); 17 | pConn->OnConnect(handle); 18 | } else { 19 | log("!!!error msg: %d\n", msg); 20 | } 21 | } 22 | 23 | int main(int argc, char* argv[]) 24 | { 25 | pid_t pid = fork(); 26 | if (pid < 0) { 27 | exit(-1); 28 | } else if (pid > 0) { 29 | exit(0); 30 | } 31 | setsid(); 32 | 33 | if ((argc == 2) && (strcmp(argv[1], "-v") == 0)) { 34 | printf("Server Version: FileServer/%s\n", VERSION); 35 | printf("Server Build: %s %s\n", __DATE__, __TIME__); 36 | return 0; 37 | } 38 | 39 | signal(SIGPIPE, SIG_IGN); 40 | 41 | CConfigFileReader config_file("fileserver.conf"); 42 | 43 | char* listen_ip = config_file.GetConfigName("Address"); 44 | char* str_listen_port = config_file.GetConfigName("ListenPort"); 45 | char* str_task_timeout = config_file.GetConfigName("TaskTimeout"); 46 | 47 | if (!listen_ip || !str_listen_port) { 48 | log("config item missing, exit...\n"); 49 | return -1; 50 | } 51 | 52 | uint16_t listen_port = atoi(str_listen_port); 53 | uint32_t task_timeout = atoi(str_task_timeout); 54 | 55 | CStrExplode listen_ip_list(listen_ip, ';'); 56 | std::list q; 57 | for (uint32_t i = 0; i < listen_ip_list.GetItemCnt(); i++) { 58 | svr_ip_addr_t t(listen_ip_list.GetItem(i), listen_port); 59 | q.push_back(t); 60 | } 61 | init_file_conn(q, task_timeout); 62 | 63 | int ret = netlib_init(); 64 | 65 | if (ret == NETLIB_ERROR) 66 | return ret; 67 | 68 | 69 | // for (uint32_t i = 0; i < listen_ip_list.GetItemCnt(); i++) { 70 | ret = netlib_listen("0.0.0.0", /*listen_ip_list.GetItem(i), */listen_port, file_serv_callback, NULL); 71 | if (ret == NETLIB_ERROR) 72 | return ret; 73 | // } 74 | 75 | printf("server start listen on %s:%d\n", listen_ip, listen_port); 76 | printf("now enter the event loop...\n"); 77 | 78 | netlib_eventloop(); 79 | 80 | printf("exiting.......\n"); 81 | log("exit\n"); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /cpp/src/file_server/fileserver.conf: -------------------------------------------------------------------------------- 1 | Address=0.0.0.0 # address for client 2 | ListenPort=8500 # Listening Port for client 3 | TaskTimeout=60 # Task Timeout (seconds) 4 | 5 | 6 | -------------------------------------------------------------------------------- /cpp/src/login_server/LoginConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * LoginConn.h 3 | * 4 | * Created on: 2013-6-21 5 | * Author: jianqingdu 6 | */ 7 | 8 | #ifndef LOGINCONN_H_ 9 | #define LOGINCONN_H_ 10 | 11 | #include "imconn.h" 12 | 13 | enum { 14 | LOGIN_CONN_TYPE_CLIENT = 1, 15 | LOGIN_CONN_TYPE_MSG_SERV 16 | }; 17 | 18 | class CLoginConn : public CImConn 19 | { 20 | public: 21 | CLoginConn(); 22 | virtual ~CLoginConn(); 23 | 24 | virtual void Close(); 25 | 26 | void OnConnect2(net_handle_t handle, int conn_type); 27 | virtual void OnClose(); 28 | virtual void OnTimer(uint64_t curr_tick); 29 | 30 | virtual void HandlePdu(CImPdu* pPdu); 31 | private: 32 | void _HandleMsgServInfo(CImPduMsgServInfo* pPdu); 33 | void _HandleUserCntUpdate(CImPduUserCntUpdate* pPdu); 34 | void _HandleMsgServRequest(CImPduMsgServRequest* pPdu); 35 | void _HandleUserConnInfo(CImPduUserConnInfo* pPdu); 36 | private: 37 | int m_conn_type; 38 | }; 39 | 40 | void init_login_conn(); 41 | 42 | #endif /* LOGINCONN_H_ */ 43 | -------------------------------------------------------------------------------- /cpp/src/login_server/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INC = ../base 4 | OPT = -Wall -Wno-deprecated -g 5 | 6 | OBJS = LoginConn.o login_server.o ../base/libbase.a 7 | 8 | SERVER = login_server 9 | 10 | all: $(SERVER) 11 | 12 | $(SERVER): $(OBJS) 13 | $(CC) $(OPT) -o $@ $(OBJS) -lpthread 14 | 15 | LoginConn.o: LoginConn.cpp 16 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 17 | 18 | login_server.o: login_server.cpp 19 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 20 | 21 | clean: 22 | rm -f $(SERVER) *.o 23 | 24 | -------------------------------------------------------------------------------- /cpp/src/login_server/login_server.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * login_server.cpp 3 | * 4 | * Created on: 2013-6-21 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #include "LoginConn.h" 9 | #include "netlib.h" 10 | #include "ConfigFileReader.h" 11 | #include "version.h" 12 | 13 | void client_callback(void* callback_data, uint8_t msg, uint32_t handle, void* pParam) 14 | { 15 | if (msg == NETLIB_MSG_CONNECT) 16 | { 17 | CLoginConn* pConn = new CLoginConn(); 18 | pConn->OnConnect2(handle, LOGIN_CONN_TYPE_CLIENT); 19 | } 20 | else 21 | { 22 | log("!!!error msg: %d\n", msg); 23 | } 24 | } 25 | 26 | // this callback will be replaced by imconn_callback() in OnConnect() 27 | void msg_serv_callback(void* callback_data, uint8_t msg, uint32_t handle, void* pParam) 28 | { 29 | if (msg == NETLIB_MSG_CONNECT) 30 | { 31 | CLoginConn* pConn = new CLoginConn(); 32 | pConn->OnConnect2(handle, LOGIN_CONN_TYPE_MSG_SERV); 33 | } 34 | else 35 | { 36 | log("!!!error msg: %d\n", msg); 37 | } 38 | } 39 | 40 | 41 | int main(int argc, char* argv[]) 42 | { 43 | if ((argc == 2) && (strcmp(argv[1], "-v") == 0)) { 44 | printf("Server Version: LoginServer/%s\n", VERSION); 45 | printf("Server Build: %s %s\n", __DATE__, __TIME__); 46 | return 0; 47 | } 48 | 49 | signal(SIGPIPE, SIG_IGN); 50 | 51 | CConfigFileReader config_file("loginserver.conf"); 52 | 53 | char* client_listen_ip = config_file.GetConfigName("ClientListenIP"); 54 | char* str_client_port = config_file.GetConfigName("ClientPort"); 55 | char* msg_server_listen_ip = config_file.GetConfigName("MsgServerListenIP"); 56 | char* str_msg_server_port = config_file.GetConfigName("MsgServerPort"); 57 | 58 | if (!client_listen_ip || !str_client_port || !msg_server_listen_ip || !str_msg_server_port) { 59 | log("config item missing, exit...\n"); 60 | return -1; 61 | } 62 | 63 | uint16_t client_port = atoi(str_client_port); 64 | uint16_t msg_server_port = atoi(str_msg_server_port); 65 | 66 | int ret = netlib_init(); 67 | 68 | if (ret == NETLIB_ERROR) 69 | return ret; 70 | 71 | CStrExplode client_listen_ip_list(client_listen_ip, ';'); 72 | for (uint32_t i = 0; i < client_listen_ip_list.GetItemCnt(); i++) { 73 | ret = netlib_listen(client_listen_ip_list.GetItem(i), client_port, client_callback, NULL); 74 | if (ret == NETLIB_ERROR) 75 | return ret; 76 | } 77 | 78 | CStrExplode msg_server_listen_ip_list(msg_server_listen_ip, ';'); 79 | for (uint32_t i = 0; i < msg_server_listen_ip_list.GetItemCnt(); i++) { 80 | ret = netlib_listen(msg_server_listen_ip_list.GetItem(i), msg_server_port, msg_serv_callback, NULL); 81 | if (ret == NETLIB_ERROR) 82 | return ret; 83 | } 84 | 85 | printf("server start listen on:\nFor client %s:%d\nFor MsgServer: %s:%d\n", 86 | client_listen_ip, client_port, msg_server_listen_ip, msg_server_port); 87 | 88 | init_login_conn(); 89 | 90 | printf("now enter the event loop...\n"); 91 | 92 | netlib_eventloop(); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /cpp/src/login_server/loginserver.conf: -------------------------------------------------------------------------------- 1 | # config format spec 2 | # this is a commet 3 | 4 | ClientListenIP=0.0.0.0 # can use multiple ip, seperate by ';' 5 | ClientPort=8008 6 | MsgServerListenIP=0.0.0.0 # can use multiple ip, seperate by ';' 7 | MsgServerPort=8100 8 | -------------------------------------------------------------------------------- /cpp/src/msfs/Makefile: -------------------------------------------------------------------------------- 1 | #基本 2 | CC = g++ 3 | CFLAGS=-Wall -Wno-deprecated -g -O2 4 | LDFLAGS= -lpthread 5 | LN=/bin/ln -s 6 | AR=ar 7 | CP=/bin/cp 8 | RM=-/bin/rm -rf 9 | ARCH=PC 10 | 11 | #链接库名 12 | LIB_NAME= 13 | #链接库版本 14 | LIB_VER=1.0.0 15 | 16 | # 二进制目标 17 | BIN=msfs 18 | 19 | #源文件目录 20 | SrcDir= . common http storage 21 | #头文件目录 22 | IncDir= . include/common include/http include/storage 23 | #连接库目录 24 | LibDir= 25 | 26 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 27 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 28 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 29 | CFLAGS := $(CFLAGS) $(INCS) 30 | LDFLAGS:= $(LINKS) $(LDFLAGS) 31 | 32 | OBJS = $(SRCS:%.cpp=%.o) 33 | .PHONY:all clean 34 | 35 | all:$(BIN) 36 | $(BIN):$(OBJS) 37 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 38 | @echo " OK!\tComplie $@ " 39 | 40 | %.o:%.cpp 41 | @echo "Compileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | 44 | .PHONY: clean 45 | clean: 46 | @echo "Cleaning files..." 47 | @$(RM) $(OBJS) $(BIN) 48 | -------------------------------------------------------------------------------- /cpp/src/msfs/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lizj3624/https-github.com-mogutt-TTServer/46e7665c6a36a577d637830bf04b78862dfd5b75/cpp/src/msfs/README -------------------------------------------------------------------------------- /cpp/src/msfs/common/SimpleBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "SimpleBuffer.h" 2 | #include 3 | #include 4 | 5 | ///////////// CSimpleBuffer //////////////// 6 | CSimpleBuffer::CSimpleBuffer() 7 | { 8 | m_buffer = NULL; 9 | 10 | m_alloc_size = 0; 11 | m_write_offset = 0; 12 | } 13 | 14 | CSimpleBuffer::~CSimpleBuffer() 15 | { 16 | m_alloc_size = 0; 17 | m_write_offset = 0; 18 | if (m_buffer) 19 | { 20 | free(m_buffer); 21 | m_buffer = NULL; 22 | } 23 | } 24 | 25 | void CSimpleBuffer::Extend(uint32_t len) 26 | { 27 | m_alloc_size = m_write_offset + len; 28 | m_alloc_size += m_alloc_size >> 2; // increase by 1/4 allocate size 29 | uchar_t* new_buf = (uchar_t*) realloc(m_buffer, m_alloc_size); 30 | if(new_buf != NULL) 31 | { 32 | m_buffer = new_buf; 33 | } 34 | } 35 | 36 | uint32_t CSimpleBuffer::Write(void* buf, uint32_t len) 37 | { 38 | if (m_write_offset + len > m_alloc_size) 39 | { 40 | Extend(len); 41 | } 42 | 43 | if (buf) 44 | { 45 | memcpy(m_buffer + m_write_offset, buf, len); 46 | } 47 | 48 | m_write_offset += len; 49 | 50 | return len; 51 | } 52 | 53 | uint32_t CSimpleBuffer::Read(void* buf, uint32_t len) 54 | { 55 | if (len > m_write_offset) 56 | len = m_write_offset; 57 | 58 | if (buf) 59 | memcpy(buf, m_buffer, len); 60 | 61 | m_write_offset -= len; 62 | memmove(m_buffer, m_buffer + len, m_write_offset); 63 | return len; 64 | } 65 | -------------------------------------------------------------------------------- /cpp/src/msfs/common/StringUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "StringUtils.h" 2 | #include 3 | 4 | namespace msfs { 5 | 6 | void replace_substrs(const char *search, 7 | size_t search_len, 8 | const char *replace, 9 | size_t replace_len, 10 | std::string *s) { 11 | size_t pos = 0; 12 | while ((pos = s->find(search, pos, search_len)) != std::string::npos) { 13 | s->replace(pos, search_len, replace, replace_len); 14 | pos += replace_len; 15 | } 16 | } 17 | 18 | bool starts_with(const char *s1, const char *s2) { 19 | return strncmp(s1, s2, strlen(s2)) == 0; 20 | } 21 | 22 | bool ends_with(const char *s1, const char *s2) { 23 | size_t s1_length = strlen(s1); 24 | size_t s2_length = strlen(s2); 25 | 26 | if (s2_length > s1_length) { 27 | return false; 28 | } 29 | 30 | const char* start = s1 + (s1_length - s2_length); 31 | return strncmp(start, s2, s2_length) == 0; 32 | } 33 | 34 | static const char kWhitespace[] = " \n\r\t"; 35 | 36 | std::string string_trim(const std::string& s) { 37 | std::string::size_type first = s.find_first_not_of(kWhitespace); 38 | std::string::size_type last = s.find_last_not_of(kWhitespace); 39 | 40 | if (first == std::string::npos || last == std::string::npos) { 41 | return std::string(""); 42 | } 43 | 44 | return s.substr(first, last - first + 1); 45 | } 46 | 47 | std::string string_prefix(const std::string& s, const char *sep) { 48 | std::string::size_type first = s.find_first_of(sep); 49 | if (first != std::string::npos) 50 | return s.substr(0, first); 51 | else 52 | return std::string(""); 53 | } 54 | 55 | 56 | std::string string_suffix(const std::string& s, const char *sep) { 57 | std::string::size_type last = s.find_last_of(sep); 58 | if (last != std::string::npos) 59 | return s.substr(last + 1); 60 | else 61 | return std::string(""); 62 | } 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /cpp/src/msfs/common/ThreadPool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ThreadPool.cpp 3 | * 4 | * Created on: 2014年7月21日 5 | * Author: ziteng 6 | */ 7 | 8 | #include 9 | #include "util.h" 10 | #include "ThreadPool.h" 11 | 12 | CThreadNotify::CThreadNotify() 13 | { 14 | pthread_mutexattr_init(&m_mutexattr); 15 | pthread_mutexattr_settype(&m_mutexattr, PTHREAD_MUTEX_RECURSIVE); 16 | pthread_mutex_init(&m_mutex, &m_mutexattr); 17 | 18 | pthread_cond_init(&m_cond, NULL); 19 | } 20 | 21 | CThreadNotify::~CThreadNotify() 22 | { 23 | pthread_mutexattr_destroy(&m_mutexattr); 24 | pthread_mutex_destroy(&m_mutex); 25 | 26 | pthread_cond_destroy(&m_cond); 27 | } 28 | 29 | //////////////////// 30 | CTask::CTask() 31 | { 32 | } 33 | 34 | CTask::~CTask() 35 | { 36 | } 37 | 38 | void CTask::run() 39 | { 40 | } 41 | 42 | /////////// 43 | CWorkerThread::CWorkerThread() 44 | { 45 | m_task_cnt = 0; 46 | } 47 | 48 | CWorkerThread::~CWorkerThread() 49 | { 50 | 51 | } 52 | 53 | void* CWorkerThread::StartRoutine(void* arg) 54 | { 55 | CWorkerThread* pThread = (CWorkerThread*)arg; 56 | 57 | pThread->Execute(); 58 | 59 | return NULL; 60 | } 61 | 62 | void CWorkerThread::Start() 63 | { 64 | (void)pthread_create(&m_thread_id, NULL, StartRoutine, this); 65 | } 66 | 67 | void CWorkerThread::Execute() 68 | { 69 | while (true) { 70 | m_thread_notify.Lock(); 71 | 72 | // put wait in while cause there can be spurious wake up (due to signal/ENITR) 73 | while (m_task_list.empty()) { 74 | m_thread_notify.Wait(); 75 | } 76 | 77 | CTask* pTask = m_task_list.front(); 78 | m_task_list.pop_front(); 79 | m_thread_notify.Unlock(); 80 | 81 | pTask->run(); 82 | 83 | delete pTask; 84 | 85 | m_task_cnt++; 86 | log("%d have the execute %d task\n", m_thread_idx, m_task_cnt); 87 | } 88 | } 89 | 90 | void CWorkerThread::PushTask(CTask* pTask) 91 | { 92 | m_thread_notify.Lock(); 93 | m_task_list.push_back(pTask); 94 | m_thread_notify.Signal(); 95 | m_thread_notify.Unlock(); 96 | } 97 | 98 | ////////////// 99 | CThreadPool::CThreadPool() 100 | { 101 | m_worker_size = 0; 102 | m_worker_list = NULL; 103 | } 104 | 105 | CThreadPool::~CThreadPool() 106 | { 107 | 108 | } 109 | 110 | int CThreadPool::Init(uint32_t worker_size) 111 | { 112 | m_worker_size = worker_size; 113 | m_worker_list = new CWorkerThread [m_worker_size]; 114 | if (!m_worker_list) { 115 | return 1; 116 | } 117 | 118 | for (uint32_t i = 0; i < m_worker_size; i++) { 119 | m_worker_list[i].SetThreadIdx(i); 120 | m_worker_list[i].Start(); 121 | } 122 | 123 | return 0; 124 | } 125 | 126 | void CThreadPool::AddTask(CTask* pTask) 127 | { 128 | /* 129 | * select a random thread to push task 130 | * we can also select a thread that has less task to do 131 | * but that will scan the whole thread list and use thread lock to get each task size 132 | */ 133 | uint32_t thread_idx = random() % m_worker_size; 134 | m_worker_list[thread_idx].PushTask(pTask); 135 | } 136 | 137 | -------------------------------------------------------------------------------- /cpp/src/msfs/common/netlib.cpp: -------------------------------------------------------------------------------- 1 | #include "netlib.h" 2 | #include "BaseSocket.h" 3 | #include "EventDispatch.h" 4 | 5 | int netlib_init() 6 | { 7 | int ret = NETLIB_OK; 8 | #ifdef _WIN32 9 | WSADATA wsaData; 10 | WORD wReqest = MAKEWORD(1, 1); 11 | if (WSAStartup(wReqest, &wsaData) != 0) 12 | { 13 | ret = NETLIB_ERROR; 14 | } 15 | #endif 16 | 17 | return ret; 18 | } 19 | 20 | int netlib_destroy() 21 | { 22 | int ret = NETLIB_OK; 23 | #ifdef _WIN32 24 | if (WSACleanup() != 0) 25 | { 26 | ret = NETLIB_ERROR; 27 | } 28 | #endif 29 | 30 | return ret; 31 | } 32 | 33 | int netlib_listen( 34 | const char* server_ip, 35 | uint16_t port, 36 | callback_t callback, 37 | void* callback_data) 38 | { 39 | CBaseSocket* pSocket = new CBaseSocket(); 40 | if (!pSocket) 41 | return NETLIB_ERROR; 42 | 43 | int ret = pSocket->Listen(server_ip, port, callback, callback_data); 44 | if (ret == NETLIB_ERROR) 45 | delete pSocket; 46 | return ret; 47 | } 48 | 49 | net_handle_t netlib_connect( 50 | const char* server_ip, 51 | uint16_t port, 52 | callback_t callback, 53 | void* callback_data) 54 | { 55 | CBaseSocket* pSocket = new CBaseSocket(); 56 | if (!pSocket) 57 | return NETLIB_INVALID_HANDLE; 58 | 59 | net_handle_t handle = pSocket->Connect(server_ip, port, callback, callback_data); 60 | if (handle == NETLIB_INVALID_HANDLE) 61 | delete pSocket; 62 | return handle; 63 | } 64 | 65 | int netlib_send(net_handle_t handle, void* buf, int len) 66 | { 67 | CBaseSocket* pSocket = FindBaseSocket(handle); 68 | if (!pSocket) 69 | return NETLIB_ERROR; 70 | 71 | int ret = pSocket->Send(buf, len); 72 | pSocket->ReleaseRef(); 73 | return ret; 74 | } 75 | 76 | int netlib_recv(net_handle_t handle, void* buf, int len) 77 | { 78 | CBaseSocket* pSocket = FindBaseSocket(handle); 79 | if (!pSocket) 80 | return NETLIB_ERROR; 81 | 82 | int ret = pSocket->Recv(buf, len); 83 | pSocket->ReleaseRef(); 84 | return ret; 85 | } 86 | 87 | int netlib_close(net_handle_t handle) 88 | { 89 | CBaseSocket* pSocket = FindBaseSocket(handle); 90 | if (!pSocket) 91 | return NETLIB_ERROR; 92 | 93 | int ret = pSocket->Close(); 94 | pSocket->ReleaseRef(); 95 | return ret; 96 | } 97 | 98 | int netlib_option(net_handle_t handle, int opt, void* optval) 99 | { 100 | CBaseSocket* pSocket = FindBaseSocket(handle); 101 | if (!pSocket) 102 | return NETLIB_ERROR; 103 | 104 | if ((opt >= NETLIB_OPT_GET_REMOTE_IP) && !optval) 105 | return NETLIB_ERROR; 106 | 107 | switch (opt) 108 | { 109 | case NETLIB_OPT_SET_CALLBACK: 110 | pSocket->SetCallback((callback_t)optval); 111 | break; 112 | case NETLIB_OPT_SET_CALLBACK_DATA: 113 | pSocket->SetCallbackData(optval); 114 | break; 115 | case NETLIB_OPT_GET_REMOTE_IP: 116 | *(string*)optval = pSocket->GetRemoteIP(); 117 | break; 118 | case NETLIB_OPT_GET_REMOTE_PORT: 119 | *(uint16_t*)optval = pSocket->GetRemotePort(); 120 | break; 121 | case NETLIB_OPT_GET_LOCAL_IP: 122 | *(string*)optval = pSocket->GetLocalIP(); 123 | break; 124 | case NETLIB_OPT_GET_LOCAL_PORT: 125 | *(uint16_t*)optval = pSocket->GetLocalPort(); 126 | } 127 | 128 | pSocket->ReleaseRef(); 129 | return NETLIB_OK; 130 | } 131 | 132 | int netlib_register_timer(callback_t callback, void* user_data, uint64_t interval) 133 | { 134 | CEventDispatch::Instance()->AddTimer(callback, user_data, interval); 135 | return 0; 136 | } 137 | 138 | int netlib_delete_timer(callback_t callback, void* user_data) 139 | { 140 | CEventDispatch::Instance()->RemoveTimer(callback, user_data); 141 | return 0; 142 | } 143 | 144 | int netlib_add_loop(callback_t callback, void* user_data) 145 | { 146 | CEventDispatch::Instance()->AddLoop(callback, user_data); 147 | return 0; 148 | } 149 | 150 | void netlib_eventloop(uint32_t wait_timeout) 151 | { 152 | CEventDispatch::Instance()->StartDispatch(wait_timeout); 153 | } 154 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/BaseSocket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * a wrap for non-block socket class for Windows, LINUX and MacOS X platform 3 | */ 4 | 5 | #ifndef __SOCKET_H__ 6 | #define __SOCKET_H__ 7 | 8 | #include "ostype.h" 9 | #include "util.h" 10 | 11 | enum 12 | { 13 | SOCKET_STATE_IDLE, 14 | SOCKET_STATE_LISTENING, 15 | SOCKET_STATE_CONNECTING, 16 | SOCKET_STATE_CONNECTED, 17 | SOCKET_STATE_CLOSING 18 | }; 19 | 20 | class CBaseSocket : public CRefObject 21 | { 22 | public: 23 | CBaseSocket(); 24 | 25 | virtual ~CBaseSocket(); 26 | 27 | SOCKET GetSocket() { return m_socket; } 28 | void SetSocket(SOCKET fd) { m_socket = fd; } 29 | void SetState(uint8_t state) { m_state = state; } 30 | 31 | void SetCallback(callback_t callback) { m_callback = callback; } 32 | void SetCallbackData(void* data) { m_callback_data = data; } 33 | void SetRemoteIP(char* ip) { m_remote_ip = ip; } 34 | void SetRemotePort(uint16_t port) { m_remote_port = port; } 35 | 36 | const char* GetRemoteIP() { return m_remote_ip.c_str(); } 37 | uint16_t GetRemotePort() { return m_remote_port; } 38 | const char* GetLocalIP() { return m_local_ip.c_str(); } 39 | uint16_t GetLocalPort() { return m_local_port; } 40 | public: 41 | int Listen( 42 | const char* server_ip, 43 | uint16_t port, 44 | callback_t callback, 45 | void* callback_data); 46 | 47 | net_handle_t Connect( 48 | const char* server_ip, 49 | uint16_t port, 50 | callback_t callback, 51 | void* callback_data); 52 | 53 | int Send(void* buf, int len); 54 | 55 | int Recv(void* buf, int len); 56 | 57 | int Close(); 58 | 59 | public: 60 | void OnRead(); 61 | void OnWrite(); 62 | void OnClose(); 63 | 64 | private: 65 | int _GetErrorCode(); 66 | bool _IsBlock(int error_code); 67 | 68 | void _SetNonblock(SOCKET fd); 69 | void _SetReuseAddr(SOCKET fd); 70 | void _SetNoDelay(SOCKET fd); 71 | void _SetAddr(const char* ip, const uint16_t port, sockaddr_in* pAddr); 72 | 73 | void _AcceptNewSocket(); 74 | 75 | private: 76 | string m_remote_ip; 77 | uint16_t m_remote_port; 78 | string m_local_ip; 79 | uint16_t m_local_port; 80 | 81 | callback_t m_callback; 82 | void* m_callback_data; 83 | 84 | uint8_t m_state; 85 | SOCKET m_socket; 86 | }; 87 | 88 | CBaseSocket* FindBaseSocket(net_handle_t fd); 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/ConfigFileReader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ConfigFileReader.h 3 | * 4 | * Created on: 2013-7-2 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef CONFIGFILEREADER_H_ 9 | #define CONFIGFILEREADER_H_ 10 | 11 | #include "util.h" 12 | 13 | class CConfigFileReader 14 | { 15 | public: 16 | CConfigFileReader(const char* filename); 17 | ~CConfigFileReader(); 18 | 19 | char* GetConfigName(const char* name); 20 | int SetConfigValue(const char* name, const char* value); 21 | private: 22 | void _LoadFile(const char* filename); 23 | int _WriteFIle(const char*filename = NULL); 24 | void _ParseLine(char* line); 25 | char* _TrimSpace(char* name); 26 | 27 | bool m_load_ok; 28 | map* m_config_map; 29 | string m_config_file; 30 | }; 31 | 32 | #endif /* CONFIGFILEREADER_H_ */ 33 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/CriticalSection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * critical section by potian@mogujie.com 3 | */ 4 | #ifndef __CRITICALSECTION_H__ 5 | #define __CRITICALSECTION_H__ 6 | 7 | namespace msfs { 8 | 9 | class CriticalSection { 10 | public: 11 | CriticalSection() { 12 | pthread_mutexattr_t mutex_attribute; 13 | pthread_mutexattr_init(&mutex_attribute); 14 | pthread_mutexattr_settype(&mutex_attribute, PTHREAD_MUTEX_RECURSIVE); 15 | pthread_mutex_init(&m_mutex, &mutex_attribute); 16 | pthread_mutexattr_destroy(&mutex_attribute); 17 | } 18 | ~CriticalSection() { 19 | pthread_mutex_destroy(&m_mutex); 20 | } 21 | void Enter() { 22 | pthread_mutex_lock(&m_mutex); 23 | } 24 | bool TryEnter() { 25 | if (pthread_mutex_trylock(&m_mutex) == 0) { 26 | return true; 27 | } 28 | return false; 29 | } 30 | void Leave() { 31 | pthread_mutex_unlock(&m_mutex); 32 | } 33 | 34 | private: 35 | pthread_mutex_t m_mutex; 36 | 37 | }; 38 | 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/EventDispatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A socket event dispatcher, features include: 3 | * 1. portable: worked both on Windows, MAC OS X, LINUX platform 4 | * 2. a singleton pattern: only one instance of this class can exist 5 | */ 6 | #ifndef __EVENT_DISPATCH_H__ 7 | #define __EVENT_DISPATCH_H__ 8 | 9 | #include "ostype.h" 10 | #include "util.h" 11 | 12 | enum { 13 | SOCKET_READ = 0x1, 14 | SOCKET_WRITE = 0x2, 15 | SOCKET_EXCEP = 0x4, 16 | SOCKET_ALL = 0x7 17 | }; 18 | 19 | class CEventDispatch 20 | { 21 | public: 22 | virtual ~CEventDispatch(); 23 | 24 | void AddEvent(SOCKET fd, uint8_t socket_event); 25 | void RemoveEvent(SOCKET fd, uint8_t socket_event); 26 | 27 | void AddTimer(callback_t callback, void* user_data, uint64_t interval); 28 | void RemoveTimer(callback_t callback, void* user_data); 29 | 30 | void AddLoop(callback_t callback, void* user_data); 31 | 32 | void StartDispatch(uint32_t wait_timeout = 100); 33 | 34 | static CEventDispatch* Instance(); 35 | protected: 36 | CEventDispatch(); 37 | 38 | private: 39 | void _CheckTimer(); 40 | void _CheckLoop(); 41 | 42 | typedef struct { 43 | callback_t callback; 44 | void* user_data; 45 | uint64_t interval; 46 | uint64_t next_tick; 47 | } TimerItem; 48 | 49 | private: 50 | #ifdef _WIN32 51 | fd_set m_read_set; 52 | fd_set m_write_set; 53 | fd_set m_excep_set; 54 | #elif __APPLE__ 55 | int m_kqfd; 56 | #else 57 | int m_epfd; 58 | #endif 59 | CThreadLock m_lock; 60 | list m_timer_list; 61 | list m_loop_list; 62 | 63 | static CEventDispatch* m_pEventDispatch; 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/SimpleBuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef _SIMPLEBUFFER_H_ 2 | #define _SIMPLEBUFFER_H_ 3 | 4 | #include "ostype.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | #ifdef WIN32 12 | #ifdef BUILD_PDU 13 | #define DLL_MODIFIER __declspec(dllexport) 14 | #else 15 | #define DLL_MODIFIER __declspec(dllimport) 16 | #endif 17 | #else 18 | #define DLL_MODIFIER 19 | #endif 20 | 21 | class DLL_MODIFIER CSimpleBuffer 22 | { 23 | public: 24 | CSimpleBuffer(); 25 | ~CSimpleBuffer(); 26 | uchar_t* GetBuffer() 27 | { 28 | return m_buffer; 29 | } 30 | uint32_t GetAllocSize() 31 | { 32 | return m_alloc_size; 33 | } 34 | uint32_t GetWriteOffset() 35 | { 36 | return m_write_offset; 37 | } 38 | void IncWriteOffset(uint32_t len) 39 | { 40 | m_write_offset += len; 41 | } 42 | 43 | void Extend(uint32_t len); 44 | uint32_t Write(void* buf, uint32_t len); 45 | uint32_t Read(void* buf, uint32_t len); 46 | private: 47 | uchar_t* m_buffer; 48 | uint32_t m_alloc_size; 49 | uint32_t m_write_offset; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/StringUtils.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace msfs { 4 | // Replaces all occurrences of "search" with "replace". 5 | void replace_substrs(const char *search, 6 | size_t search_len, 7 | const char *replace, 8 | size_t replace_len, 9 | std::string *s); 10 | 11 | // True iff s1 starts with s2. 12 | bool starts_with(const char *s1, const char *s2); 13 | 14 | // True iff s1 ends with s2. 15 | bool ends_with(const char *s1, const char *s2); 16 | 17 | // Remove leading and trailing whitespaces. 18 | std::string string_trim(const std::string& s); 19 | 20 | std::string string_prefix(const std::string& s, const char *sep = "."); 21 | std::string string_suffix(const std::string& s, const char *sep = "."); 22 | } 23 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/ThreadPool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ThreadPool.h 3 | * 4 | * Created on: 2014年7月21日 5 | * Author: ziteng 6 | */ 7 | 8 | #ifndef THREADPOOL_H_ 9 | #define THREADPOOL_H_ 10 | 11 | #include 12 | #include 13 | #include "ostype.h" 14 | using namespace std; 15 | 16 | class CThreadNotify 17 | { 18 | public: 19 | CThreadNotify(); 20 | ~CThreadNotify(); 21 | void Lock() { pthread_mutex_lock(&m_mutex); } 22 | void Unlock() { pthread_mutex_unlock(&m_mutex); } 23 | void Wait() { pthread_cond_wait(&m_cond, &m_mutex); } 24 | void Signal() { pthread_cond_signal(&m_cond); } 25 | private: 26 | pthread_mutex_t m_mutex; 27 | pthread_mutexattr_t m_mutexattr; 28 | 29 | pthread_cond_t m_cond; 30 | }; 31 | 32 | class CTask { 33 | public: 34 | CTask(); 35 | virtual ~CTask(); 36 | 37 | virtual void run() = 0; 38 | private: 39 | }; 40 | 41 | class CWorkerThread { 42 | public: 43 | CWorkerThread(); 44 | ~CWorkerThread(); 45 | 46 | static void* StartRoutine(void* arg); 47 | 48 | void Start(); 49 | void Execute(); 50 | void PushTask(CTask* pTask); 51 | 52 | void SetThreadIdx(uint32_t idx) { m_thread_idx = idx; } 53 | private: 54 | 55 | uint32_t m_thread_idx; 56 | uint32_t m_task_cnt; 57 | pthread_t m_thread_id; 58 | CThreadNotify m_thread_notify; 59 | list m_task_list; 60 | }; 61 | 62 | class CThreadPool { 63 | public: 64 | CThreadPool(); 65 | virtual ~CThreadPool(); 66 | 67 | int Init(uint32_t worker_size); 68 | void AddTask(CTask* pTask); 69 | private: 70 | uint32_t m_worker_size; 71 | CWorkerThread* m_worker_list; 72 | }; 73 | 74 | 75 | 76 | #endif /* THREADPOOL_H_ */ 77 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/atomic.h: -------------------------------------------------------------------------------- 1 | #ifndef _ATOMIC_H_ 2 | #define _ATOMIC_H_ 3 | 4 | #define ATOMIC_ADD(src_ptr, v) (void)__sync_add_and_fetch(src_ptr, v) 5 | #define ATOMIC_SUB_AND_FETCH(src_ptr, v) __sync_sub_and_fetch(src_ptr, v) 6 | #define ATOMIC_ADD_AND_FETCH(src_ptr, v) __sync_add_and_fetch(src_ptr, v) 7 | #define ATOMIC_FETCH(src_ptr) __sync_add_and_fetch(src_ptr, 0) 8 | #define ATOMIC_SET(src_ptr, v) (void)__sync_bool_compare_and_swap(src_ptr, *(src_ptr), v) 9 | 10 | typedef volatile long atomic_t; 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/netlib.h: -------------------------------------------------------------------------------- 1 | #ifndef __NETLIB_H__ 2 | #define __NETLIB_H__ 3 | 4 | #include "ostype.h" 5 | 6 | #define NETLIB_OPT_SET_CALLBACK 1 7 | #define NETLIB_OPT_SET_CALLBACK_DATA 2 8 | #define NETLIB_OPT_GET_REMOTE_IP 3 9 | #define NETLIB_OPT_GET_REMOTE_PORT 4 10 | #define NETLIB_OPT_GET_LOCAL_IP 5 11 | #define NETLIB_OPT_GET_LOCAL_PORT 6 12 | 13 | #define NETLIB_MAX_SOCKET_BUF_SIZE (128 * 1024) 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | int netlib_init(); 20 | 21 | int netlib_destroy(); 22 | 23 | int netlib_listen( 24 | const char* server_ip, 25 | uint16_t port, 26 | callback_t callback, 27 | void* callback_data); 28 | 29 | net_handle_t netlib_connect( 30 | const char* server_ip, 31 | uint16_t port, 32 | callback_t callback, 33 | void* callback_data); 34 | 35 | int netlib_send(net_handle_t handle, void* buf, int len); 36 | 37 | int netlib_recv(net_handle_t handle, void* buf, int len); 38 | 39 | int netlib_close(net_handle_t handle); 40 | 41 | int netlib_option(net_handle_t handle, int opt, void* optval); 42 | 43 | int netlib_register_timer(callback_t callback, void* user_data, uint64_t interval); 44 | 45 | int netlib_delete_timer(callback_t callback, void* user_data); 46 | 47 | int netlib_add_loop(callback_t callback, void* user_data); 48 | 49 | void netlib_eventloop(uint32_t wait_timeout = 100); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/ostype.h: -------------------------------------------------------------------------------- 1 | // OS dependant type definition 2 | #ifndef __OS_TYPE_H__ 3 | #define __OS_TYPE_H__ 4 | 5 | #ifdef _WIN32 6 | #include 7 | #include 8 | #else 9 | #ifdef __APPLE__ 10 | #include 11 | #include 12 | #include // syscall(SYS_gettid) 13 | #else 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include // define int8_t ... 28 | #include 29 | #define closesocket close 30 | #define ioctlsocket ioctl 31 | #endif 32 | 33 | #ifdef _WIN32 34 | typedef char int8_t; 35 | typedef short int16_t; 36 | typedef int int32_t; 37 | typedef long long int64_t; 38 | typedef unsigned char uint8_t; 39 | typedef unsigned short uint16_t; 40 | typedef unsigned int uint32_t; 41 | typedef unsigned long long uint64_t; 42 | typedef int socklen_t; 43 | #else 44 | #ifdef linux 45 | const int TRUE = 1; 46 | const int FALSE = 0; 47 | #endif 48 | typedef int SOCKET; 49 | typedef int BOOL; 50 | const int SOCKET_ERROR = -1; 51 | const int INVALID_SOCKET = -1; 52 | #endif 53 | 54 | typedef unsigned char uchar_t; 55 | typedef int net_handle_t; 56 | typedef int conn_handle_t; 57 | 58 | enum { 59 | NETLIB_OK = 0, 60 | NETLIB_ERROR = -1 61 | }; 62 | 63 | #define NETLIB_INVALID_HANDLE -1 64 | 65 | enum 66 | { 67 | NETLIB_MSG_CONNECT = 1, 68 | NETLIB_MSG_CONFIRM, 69 | NETLIB_MSG_READ, 70 | NETLIB_MSG_WRITE, 71 | NETLIB_MSG_CLOSE, 72 | NETLIB_MSG_TIMER, 73 | NETLIB_MSG_LOOP, 74 | }; 75 | 76 | typedef void (*callback_t)(void* callback_data, uint8_t msg, uint32_t handle, void* pParam); 77 | 78 | //windows 79 | #ifdef _WIN32 80 | #define MSFS_WIN 1 81 | #endif 82 | 83 | //linux 84 | #ifdef linux 85 | #define MSFS_LINUX 1 86 | #endif 87 | 88 | //freebsd 89 | #ifdef __FreeBSD__ 90 | #define MSFS_BSD 1 91 | #endif 92 | 93 | #ifdef __APPLE__ 94 | #define MSFS_BSD 1 95 | #endif 96 | //unix 97 | #ifdef _UNIX 98 | #define MSFS_UNIX 1 99 | #endif 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/common/util.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTIL_H__ 2 | #define __UTIL_H__ 3 | 4 | #define _CRT_SECURE_NO_DEPRECATE // remove warning C4996, 5 | 6 | #include "ostype.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #ifdef _WIN32 13 | #define snprintf sprintf_s 14 | #else 15 | #include 16 | #include 17 | #include 18 | #include 19 | #endif 20 | 21 | #ifdef _WIN32 22 | #include 23 | using namespace stdext; 24 | #else 25 | #include 26 | using namespace __gnu_cxx; 27 | #endif 28 | 29 | using namespace std; 30 | 31 | #define MAX_LOG_FILE_SIZE 0x4000000 // 64MB 32 | #define NOTUSED_ARG(v) ((void)v) // used this to remove warning C4100, unreferenced parameter 33 | 34 | class CThread 35 | { 36 | public: 37 | CThread(); 38 | virtual ~CThread(); 39 | 40 | #ifdef _WIN32 41 | static DWORD WINAPI StartRoutine(LPVOID lpParameter); 42 | #else 43 | static void* StartRoutine(void* arg); 44 | #endif 45 | 46 | virtual void StartThread(void); 47 | virtual void OnThreadRun(void) = 0; 48 | protected: 49 | #ifdef _WIN32 50 | DWORD m_thread_id; 51 | #else 52 | pthread_t m_thread_id; 53 | #endif 54 | }; 55 | 56 | class CEventThread: public CThread 57 | { 58 | public: 59 | CEventThread(); 60 | virtual ~CEventThread(); 61 | 62 | virtual void OnThreadTick(void) = 0; 63 | virtual void OnThreadRun(void); 64 | virtual void StartThread(); 65 | virtual void StopThread(); 66 | bool IsRunning() 67 | { 68 | return m_bRunning; 69 | } 70 | private: 71 | bool m_bRunning; 72 | }; 73 | 74 | class CThreadLock 75 | { 76 | public: 77 | CThreadLock(); 78 | ~CThreadLock(); 79 | void Lock(void); 80 | void Unlock(void); 81 | private: 82 | #ifdef _WIN32 83 | CRITICAL_SECTION m_critical_section; 84 | #else 85 | pthread_mutex_t m_mutex; 86 | pthread_mutexattr_t m_mutexattr; 87 | #endif 88 | }; 89 | 90 | class CFuncLock 91 | { 92 | public: 93 | CFuncLock(CThreadLock* lock) 94 | { 95 | m_lock = lock; 96 | if (m_lock) 97 | m_lock->Lock(); 98 | } 99 | 100 | ~CFuncLock() 101 | { 102 | if (m_lock) 103 | m_lock->Unlock(); 104 | } 105 | private: 106 | CThreadLock* m_lock; 107 | }; 108 | 109 | class CRefObject 110 | { 111 | public: 112 | CRefObject(); 113 | virtual ~CRefObject(); 114 | 115 | void SetLock(CThreadLock* lock) 116 | { 117 | m_lock = lock; 118 | } 119 | void AddRef(); 120 | void ReleaseRef(); 121 | private: 122 | int m_refCount; 123 | CThreadLock* m_lock; 124 | }; 125 | 126 | void log(const char* fmt, ...); 127 | 128 | uint64_t get_tick_count(); 129 | void util_sleep(uint32_t millisecond); 130 | 131 | class CStrExplode 132 | { 133 | public: 134 | CStrExplode(char* str, char seperator); 135 | virtual ~CStrExplode(); 136 | 137 | uint32_t GetItemCnt() 138 | { 139 | return m_item_cnt; 140 | } 141 | char* GetItem(uint32_t idx) 142 | { 143 | return m_item_list[idx]; 144 | } 145 | private: 146 | uint32_t m_item_cnt; 147 | char** m_item_list; 148 | }; 149 | 150 | #include 151 | 152 | int64_t get_file_size(const char *path); 153 | const char* memfind(const char *src_str,size_t src_len, const char *sub_str, size_t sub_len, bool flag = true); 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/storage/FileLin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Multimdia Small File Storage Sytem 3 | * File Operation In Linux System 4 | * @author potian@mogujie.com 5 | */ 6 | 7 | #ifndef _FILELIN_H_ 8 | #define _FILELIN_H_ 9 | 10 | #include "Portable.h" 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | namespace msfs { 18 | 19 | class File { 20 | public: 21 | File(const char *path); 22 | ~File(); 23 | const char* getPath() const { 24 | return m_path; 25 | } 26 | u64 create(bool directIo = false); 27 | u64 remove(); 28 | u64 open(bool directIo = false); 29 | u64 close(); 30 | 31 | u64 isExist(bool *exist); 32 | static bool isExist(const char *path) { 33 | bool exist = false; 34 | File(path).isExist(&exist); 35 | return exist; 36 | } 37 | 38 | static u64 mkdirNoRecursion(const char *path); 39 | u64 isDirectory(bool *isDir); 40 | 41 | u64 getFileNum(int *fileNum); 42 | int getFd() { return m_opened == false ? -1 : m_file;} 43 | u64 read(u64 offset, u32 size, void *buffer); 44 | u64 write(u64 offset,u32 size, const void *buffer); 45 | u64 sync(); 46 | 47 | static s64 getFileSize(const char *path); 48 | u64 getSize(u64 *size); 49 | u64 setSize(u64 size); 50 | 51 | static const char* explainErrno(u64 code) { 52 | switch ((u32)code) { 53 | case E_NO_ERROR: 54 | return "no error"; 55 | case E_NOT_EXIST: 56 | return "file not exist"; 57 | case E_PERM_ERR: 58 | return "permission deny"; 59 | case E_DISK_FULL: 60 | return "disk is full"; 61 | case E_EXISTS: 62 | return "file already exist"; 63 | case E_IN_USE: 64 | return "file is in use"; 65 | case E_READ: 66 | return "read failed"; 67 | case E_WRITE: 68 | return "write failed"; 69 | case E_EOF: 70 | return "end of file exceeded"; 71 | default: 72 | return "other reasons"; 73 | } 74 | } 75 | 76 | public: 77 | //error code 78 | static const u64 E_NO_ERROR = 0; 79 | static const u32 E_NOT_EXIST = 1; 80 | static const u64 E_PERM_ERR = 2; 81 | static const u64 E_DISK_FULL = 3; 82 | static const u64 E_EXISTS = 4; 83 | static const u64 E_IN_USE = 5; 84 | static const u64 E_EOF = 6; 85 | static const u64 E_READ = 7; 86 | static const u64 E_WRITE = 8; 87 | static const u64 E_NO_EMPTY = 9; 88 | static const u64 E_OTHER = 10; 89 | 90 | private: 91 | char *m_path; //file full path 92 | bool m_opened; //file has opened 93 | s64 m_size; //file size 94 | int m_file; //file fd, -1 while the file no exists or opened 95 | bool m_directIo;//file open with directIO no OS buffer 96 | }; 97 | 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/storage/FileManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Multimedia Small File Storage System 3 | * FileManager Singleton to manager store or download file 4 | * author potian@mogujie.com 5 | */ 6 | 7 | #ifndef _FILEMANAGER_H_ 8 | #define _FILEMANAGER_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "FileLin.h" 20 | #include "CriticalSection.h" 21 | 22 | using namespace std; 23 | 24 | namespace msfs { 25 | class CriticalSection; 26 | class FileManager { 27 | private: 28 | FileManager() {} 29 | FileManager(const char *host, const char *disk, 30 | int totFiles, int filesPerDir) { 31 | m_host = new char[strlen(host) + 1]; 32 | m_disk = new char[strlen(disk) + 1]; 33 | m_host[strlen(host)] = '\0'; 34 | m_disk[strlen(disk)] = '\0'; 35 | strncpy(m_host, host, strlen(host)); 36 | strncpy(m_disk, disk, strlen(disk)); 37 | m_totFiles = totFiles; 38 | m_filesPerDir = filesPerDir; 39 | m_map.clear(); 40 | } 41 | ~FileManager() { 42 | if (m_host) 43 | delete [] m_host; 44 | m_host = NULL; 45 | if (m_disk) 46 | delete [] m_disk; 47 | m_disk = NULL; 48 | EntryMap::iterator it = m_map.begin(); 49 | while (it != m_map.end()) { 50 | delete it->second; 51 | m_map.erase(it++); 52 | } 53 | } 54 | 55 | FileManager(const FileManager &); 56 | FileManager operator=(const FileManager &); 57 | 58 | public: 59 | static FileManager* getInstance(const char *host, const char *disk, int totFiles, int filesPerDir) { 60 | return (m_instance) ? m_instance : \ 61 | (new FileManager(host, disk, totFiles, filesPerDir)); 62 | } 63 | 64 | static void destroyInstance() { 65 | if (m_instance) 66 | delete m_instance; 67 | m_instance = NULL; 68 | } 69 | 70 | int initDir(); 71 | u64 getFileCntCurr() {return m_totFiles;} 72 | int getFirstDir() {return (m_totFiles / (m_filesPerDir)) / (FIRST_DIR_MAX);} 73 | int getSecondDir() {return (m_totFiles % (m_filesPerDir * FIRST_DIR_MAX) ) / m_filesPerDir;} 74 | 75 | string createFileRelatePath(); 76 | int uploadFile(const char *type, const void *content, u32 size, char *url, char *ext = NULL); 77 | int downloadFileByUrl(char *urlEn, void *buf, u32 *size); 78 | int getRelatePathByUrl(const string &url, string &path); 79 | int getAbsPathByUrl(const string &url, string &path); 80 | 81 | protected: 82 | struct Entry { 83 | time_t m_lastAccess; 84 | size_t m_fileSize; 85 | u8* m_fileContent; 86 | Entry() { 87 | m_lastAccess = 0; 88 | m_fileSize = 0; 89 | m_fileContent = NULL; 90 | } 91 | ~Entry() { 92 | if (m_fileContent) 93 | delete [] m_fileContent; 94 | m_fileContent = NULL; 95 | } 96 | }; 97 | typedef std::map EntryMap; 98 | int insertEntry(const std::string& url, size_t filesize, 99 | const void* content); 100 | Entry* getEntry(const std::string& url) const { 101 | return const_cast(this)->getOrCreateEntry(url,false); 102 | } 103 | Entry* getOrCreateEntry(const std::string& url, bool create); 104 | void releaseFileCache(const std::string& url); 105 | void updateMapCache(); 106 | 107 | private: 108 | char *m_host; //msfs server ip or hostname 109 | char *m_disk; //storage directory of media files 110 | u64 m_totFiles; //total files has storaged 111 | CriticalSection m_filesCs; 112 | 113 | int m_filesPerDir; //mas file nums per dir eg. xxx/xxx 114 | static const u32 MAX_FILE_SIZE_PER_FILE = 5 * 1024 * 1024; 115 | static const int FIRST_DIR_MAX =255; 116 | static const int SECOND_DIR_MAX =255; 117 | static FileManager * m_instance; 118 | EntryMap m_map; 119 | static const u64 MAX_FILE_IN_MAP = 10000; 120 | CriticalSection m_cs; 121 | }; 122 | 123 | } 124 | 125 | #endif 126 | 127 | -------------------------------------------------------------------------------- /cpp/src/msfs/include/storage/Portable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 数据类型与一些可移植相关定义 3 | * 4 | */ 5 | 6 | #ifndef _PORTABLE_H_ 7 | #define _PORTABLE_H_ 8 | 9 | typedef signed char s8; 10 | typedef unsigned char u8; 11 | typedef signed short s16; 12 | typedef unsigned short u16; 13 | typedef signed int s32; 14 | typedef unsigned int u32; 15 | typedef long long s64; 16 | typedef unsigned long long u64; 17 | typedef unsigned int uint; 18 | typedef unsigned char byte; 19 | 20 | #ifndef LITTLE_ENDIAN 21 | #define LITTLE_ENDIAN 22 | #endif 23 | 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /cpp/src/msfs/msfs.conf.example: -------------------------------------------------------------------------------- 1 | ListenIP= #可以监听多个IP,用;分割 2 | ListenPort= 3 | BaseDir= 4 | FileCnt=0 5 | FilesPerDir=30000 6 | GetThreadCount=32 7 | PostThreadCount=1 8 | -------------------------------------------------------------------------------- /cpp/src/msg_server/AttachData.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * AttachData.cpp 3 | * 4 | * Created on: 2014年4月16日 5 | * Author: ziteng 6 | */ 7 | 8 | 9 | #include "AttachData.h" 10 | 11 | CDbAttachData::CDbAttachData(uint32_t type, uint32_t handle, uint32_t service_type /* = 0 */) // 序列化 12 | { 13 | CByteStream os(&m_buf, 0); 14 | 15 | os << type; 16 | os << handle; 17 | os << service_type; 18 | } 19 | 20 | CDbAttachData::CDbAttachData(uchar_t* attach_data, uint32_t attach_len) // 反序列化 21 | { 22 | CByteStream is(attach_data, attach_len); 23 | 24 | is >> m_type; 25 | is >> m_handle; 26 | is >> m_service_type; 27 | } 28 | 29 | CPduAttachData::CPduAttachData(uint32_t type, uint32_t handle, uint32_t pduLength, uchar_t* pdu, uint32_t service_type) // 序列化 30 | { 31 | CByteStream os(&m_buf, 0); 32 | 33 | os << type; 34 | os << handle; 35 | os << service_type; 36 | os.WriteData(pdu, pduLength); 37 | } 38 | 39 | CPduAttachData::CPduAttachData(uchar_t* attach_data, uint32_t attach_len) // 反序列化 40 | { 41 | CByteStream is(attach_data, attach_len); 42 | 43 | is >> m_type; 44 | is >> m_handle; 45 | is >> m_service_type; 46 | m_pdu = is.ReadData(m_pduLength); 47 | } -------------------------------------------------------------------------------- /cpp/src/msg_server/AttachData.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AttachData.h 3 | * 4 | * Created on: 2014年4月16日 5 | * Author: ziteng 6 | */ 7 | 8 | #ifndef ATTACHDATA_H_ 9 | #define ATTACHDATA_H_ 10 | 11 | #include "util.h" 12 | 13 | enum { 14 | ATTACH_TYPE_HANDLE = 1, 15 | ATTACH_TYPE_SHOP_ID = 2, 16 | ATTACH_TYPE_HANDLE_AND_PDU = 3, 17 | }; 18 | 19 | class CDbAttachData 20 | { 21 | public: 22 | CDbAttachData(uint32_t type, uint32_t handle, uint32_t service_type = 0); // 序列化 23 | CDbAttachData(uchar_t* attach_data, uint32_t attach_len); // 反序列化 24 | virtual ~CDbAttachData() {} 25 | 26 | uchar_t* GetBuffer() {return m_buf.GetBuffer(); } 27 | uint32_t GetLength() { return m_buf.GetWriteOffset(); } 28 | uint32_t GetType() { return m_type; } 29 | uint32_t GetHandle() { return m_handle; } 30 | uint32_t GetServiceType() { return m_service_type; } 31 | private: 32 | CSimpleBuffer m_buf; 33 | uint32_t m_type; 34 | uint32_t m_handle; 35 | uint32_t m_service_type; 36 | }; 37 | 38 | class CPduAttachData 39 | { 40 | public: 41 | CPduAttachData(uint32_t type, uint32_t handle, uint32_t pduLength, uchar_t* pdu, uint32_t service_type = 0); // 序列化 42 | CPduAttachData(uchar_t* attach_data, uint32_t attach_len); // 反序列化 43 | virtual ~CPduAttachData() {} 44 | 45 | uchar_t* GetBuffer() {return m_buf.GetBuffer(); } 46 | uint32_t GetLength() { return m_buf.GetWriteOffset(); } 47 | uint32_t GetType() { return m_type; } 48 | uint32_t GetHandle() { return m_handle; } 49 | uint32_t GetServiceType() { return m_service_type; } 50 | uint32_t GetPduLength() { return m_pduLength; } 51 | uchar_t* GetPdu() { return m_pdu; } 52 | private: 53 | CSimpleBuffer m_buf; 54 | uint32_t m_type; 55 | uint32_t m_handle; 56 | uint32_t m_service_type; 57 | uint32_t m_pduLength; 58 | uchar_t* m_pdu; 59 | }; 60 | 61 | #endif /* ATTACHDATA_H_ */ 62 | -------------------------------------------------------------------------------- /cpp/src/msg_server/DBServConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DBServConn.h 3 | * 4 | * Created on: 2013-7-8 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef DBSERVCONN_H_ 9 | #define DBSERVCONN_H_ 10 | 11 | #include "imconn.h" 12 | #include "ServInfo.h" 13 | #include "RouteServConn.h" 14 | 15 | class CDBServConn : public CImConn 16 | { 17 | public: 18 | CDBServConn(); 19 | virtual ~CDBServConn(); 20 | 21 | bool IsOpen() { return m_bOpen; } 22 | 23 | void Connect(const char* server_ip, uint16_t server_port, uint32_t serv_idx); 24 | virtual void Close(); 25 | 26 | virtual void OnConfirm(); 27 | virtual void OnClose(); 28 | virtual void OnTimer(uint64_t curr_tick); 29 | 30 | virtual void HandlePdu(CImPdu* pPdu); 31 | private: 32 | void _HandleValidateResponse(CImPduValidateResponse* pPdu); 33 | void _HandleFriendListResponse(CImPduFriendListResponse* pPdu); 34 | void _HandleUnreadMsgCountResponse(CImPduUnreadMsgCountResponse* pPdu); 35 | void _HandleMsgListResponse(CImPduMsgListResponse* pPdu); 36 | void _HandleDBWriteResponse(CImPduDBWriteResponse* pPdu); 37 | void _HandleUsersInfoResponse(CImPduUsersInfoResponse* pPdu); 38 | void _HandleStopReceivePacket(CImPduStopReceivePacket* pPdu); 39 | void _HandleDBQueryResponse(CImPduDBQueryResponse* pPdu); 40 | void _HandleRemoveSessionResponse(CImPduRemoveSessionResponse* pPdu); 41 | void _HandleDepartmentResponse(CImPduDepartmentResponse* pPdu); 42 | private: 43 | bool m_bOpen; 44 | uint32_t m_serv_idx; 45 | }; 46 | 47 | void init_db_serv_conn(serv_info_t* server_list, uint32_t server_count, uint32_t concur_conn_cnt); 48 | string create_uuid(); 49 | 50 | CDBServConn* get_db_serv_conn_for_login(); 51 | CDBServConn* get_db_serv_conn(); 52 | 53 | #endif /* DBSERVCONN_H_ */ 54 | -------------------------------------------------------------------------------- /cpp/src/msg_server/FileHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FileHandler.h 3 | * 4 | * Created on: 2013-12-17 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef FILEHANDLER_H_ 9 | #define FILEHANDLER_H_ 10 | 11 | #include "impdu.h" 12 | 13 | class CMsgConn; 14 | 15 | class CFileHandler 16 | { 17 | public: 18 | virtual ~CFileHandler() {} 19 | 20 | static CFileHandler* getInstance(); 21 | 22 | void HandleClientFileRequest(CMsgConn* pMsgConn, CImPduClientFileRequest* pPdu); 23 | void HandleClientFileHasOfflineReq(CMsgConn* pMsgConn, CImPduClientFileHasOfflineReq* pPdu); 24 | void HandleClientFileAddOfflineReq(CImPduClientFileAddOfflineReq* pPdu); 25 | void HandleClientFileDelOfflineReq(CImPduClientFileDelOfflineReq* pPdu); 26 | void HandleFileHasOfflineRes(CImPduFileHasOfflineRes* pPdu); 27 | void HandleFileNotify(CImPduFileNotify* pPdu); 28 | private: 29 | CFileHandler() {} 30 | 31 | private: 32 | static CFileHandler* s_handler_instance; 33 | }; 34 | 35 | 36 | #endif /* FILEHANDLER_H_ */ 37 | -------------------------------------------------------------------------------- /cpp/src/msg_server/FileServConn.h: -------------------------------------------------------------------------------- 1 | // 2 | // FileServConn.h 3 | // public_TTServer 4 | // 5 | // Created by luoning on 14-8-19. 6 | // Copyright (c) 2014年 luoning. All rights reserved. 7 | // 8 | 9 | #ifndef __FileServConn__ 10 | #define __FileServConn__ 11 | 12 | #include 13 | 14 | #include "imconn.h" 15 | #include "ServInfo.h" 16 | #include "BaseSocket.h" 17 | class CFileServConn : public CImConn 18 | { 19 | public: 20 | CFileServConn(); 21 | virtual ~CFileServConn(); 22 | 23 | bool IsOpen() { return m_bOpen; } 24 | 25 | void Connect(const char* server_ip, uint16_t server_port, uint32_t serv_idx); 26 | virtual void Close(); 27 | 28 | virtual void OnConfirm(); 29 | virtual void OnClose(); 30 | virtual void OnTimer(uint64_t curr_tick); 31 | 32 | virtual void HandlePdu(CImPdu* pPdu); 33 | 34 | const list* GetFileServerIPList() { return &m_ip_list; } 35 | 36 | private: 37 | void _HandleFileMsgTransRsp(CImPduMsgFileTransferRsp* pPdu); 38 | void _HandleFileServerIPRsp(CImPduFileServerIPRsp* pPdu); 39 | 40 | private: 41 | bool m_bOpen; 42 | uint32_t m_serv_idx; 43 | uint64_t m_connect_time; 44 | list m_ip_list; 45 | }; 46 | 47 | void init_file_serv_conn(serv_info_t* server_list, uint32_t server_count); 48 | bool is_file_server_available(); 49 | CFileServConn* get_random_file_serv_conn(); 50 | #endif /* defined(__FileServConn__) */ 51 | -------------------------------------------------------------------------------- /cpp/src/msg_server/GroupChat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * GroupChat.h 3 | * 4 | * Created on: 2014-1-3 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef GROUPCHAT_H_ 9 | #define GROUPCHAT_H_ 10 | 11 | #include "impdu.h" 12 | 13 | typedef set group_member_t; 14 | typedef hash_map group_map_t; 15 | 16 | class CMsgConn; 17 | 18 | class CGroupChat 19 | { 20 | public: 21 | virtual ~CGroupChat() {} 22 | 23 | static CGroupChat* GetInstance(); 24 | 25 | void HandleClientGroupListRequest(CImPduClientGroupListRequest* pPdu, CMsgConn* pFromConn); 26 | void HandleGroupListResponse(CImPduGroupListResponse* pPdu); 27 | 28 | void HandleClientGroupUserListRequest(CImPduClientGroupUserListRequest* pPdu, CMsgConn* pFromConn); 29 | void HandleGroupUserListResponse(CImPduGroupUserListResponse* pPdu); 30 | 31 | void HandleClientGroupMessage(CImPduClientMsgData* pPdu, CMsgConn* pFromConn); 32 | void HandleGroupMessage(CImPduMsgData* pPdu); 33 | 34 | void HandleClientGroupUnreadMsgCntRequest(CImPduClientGroupUnreadMsgCntRequest* pPdu, CMsgConn* pFromConn); 35 | void HandleGroupUnreadMsgCntResponse(CImPduGroupUnreadMsgCntResponse* pPdu); 36 | 37 | void HandleClientGroupUnreadMsgRequest(CImPduClientGroupUnreadMsgRequest* pPdu, CMsgConn* pFromConn); 38 | 39 | void HandleGroupMsgListResponse(CImPduGroupMsgListResponse* pPdu); 40 | 41 | void HandleClientGroupMsgReadAck(CImPduClientGroupMsgReadAck* pPdu, CMsgConn* pFromConn); 42 | 43 | void HandleClientGroupCreateTmpGroupRequest(CImPduClientGroupCreateTmpGroupRequest* pPdu, CMsgConn* pFromConn); 44 | void HandleGroupCreateTmpGroupResponse(CImPduGroupCreateTmpGroupResponse* pPdu); 45 | void HandleGroupCreateTmpGroupBroadcast(CImPduGroupCreateTmpGroupResponse* pPdu); 46 | void HandleClientGroupChangeMemberRequest(CImPduClientGroupChangeMemberRequest* pPdu, CMsgConn* pFromConn); 47 | void HandleGroupChangeMemberResponse(CImPduGroupChangeMemberResponse* pPdu); 48 | void HandleGroupChangeMemberBroadcast(CImPduGroupChangeMemberResponse* pPdu); 49 | void HandleGroupCreateNormalGroupNotify(CImPduGroupCreateNormalGroupNotify* pdu); 50 | void HandleGroupChangeMemberNotify(CImPduGroupChangeMemberNotify* pdu); 51 | void HandleGroupCreateNormalGroupNotify(uint32_t group_id, const char* group_name, 52 | const char* group_avatar, uint32_t user_cnt, uint32_t* user_list); 53 | void HandleGroupChangeMemberNotify(uint32_t group_id, uint32_t user_cnt, uint32_t* user_list); 54 | 55 | private: 56 | CGroupChat() {} // for singleton; 57 | 58 | void _UpdateGroupMap(uint32_t group_id, list* user_list); 59 | void _UpdateGroupMap(uint32_t group_id, uint32_t user_cnt, uint32_t* user_list); 60 | group_member_t* _GetGroupMember(uint32_t group_id); 61 | void _JoinGroup(uint32_t group_id, uint32_t user_cnt, uint32_t* user_list); 62 | void _QuitGroup(uint32_t group_id, uint32_t user_cnt, uint32_t* user_list); 63 | void _SendPduToUser(CImPdu* pPdu, uint32_t user_id); 64 | private: 65 | 66 | static CGroupChat* s_group_chat_instance; 67 | 68 | group_map_t m_group_map; 69 | }; 70 | 71 | 72 | #endif /* GROUPCHAT_H_ */ 73 | -------------------------------------------------------------------------------- /cpp/src/msg_server/HttpConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpConn.h 3 | * 4 | * Created on: 2013-9-29 5 | * Author: ziteng 6 | */ 7 | 8 | #ifndef __HTTP_CONN_H__ 9 | #define __HTTP_CONN_H__ 10 | 11 | #include "netlib.h" 12 | #include "util.h" 13 | 14 | #define HTTP_CONN_TIMEOUT 60000 15 | 16 | #define READ_BUF_SIZE 2048 17 | 18 | enum { 19 | CONN_STATE_IDLE, 20 | CONN_STATE_CONNECTED, 21 | CONN_STATE_OPEN, 22 | CONN_STATE_CLOSED, 23 | }; 24 | 25 | class CHttpConn : public CRefObject 26 | { 27 | public: 28 | CHttpConn(); 29 | virtual ~CHttpConn(); 30 | 31 | uint32_t GetConnHandle() { return m_conn_handle; } 32 | char* GetPeerIP() { return (char*)m_peer_ip.c_str(); } 33 | 34 | int Send(void* data, int len); 35 | 36 | void Close(); 37 | void OnConnect(net_handle_t handle); 38 | void OnRead(); 39 | void OnWrite(); 40 | void OnClose(); 41 | void OnTimer(uint64_t curr_tick); 42 | 43 | protected: 44 | net_handle_t m_sock_handle; 45 | uint32_t m_conn_handle; 46 | bool m_busy; 47 | 48 | uint32_t m_state; 49 | std::string m_peer_ip; 50 | uint16_t m_peer_port; 51 | CSimpleBuffer m_in_buf; 52 | CSimpleBuffer m_out_buf; 53 | 54 | uint64_t m_last_send_tick; 55 | uint64_t m_last_recv_tick; 56 | }; 57 | 58 | typedef hash_map HttpConnMap_t; 59 | 60 | CHttpConn* FindHttpConnByHandle(uint32_t handle); 61 | void init_http_conn(); 62 | 63 | #endif /* IMCONN_H_ */ 64 | -------------------------------------------------------------------------------- /cpp/src/msg_server/HttpParserWrapper.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // HttpPdu.cpp 3 | // http_msg_server 4 | // 5 | // Created by jianqing.du on 13-9-29. 6 | // Copyright (c) 2013年 ziteng. All rights reserved. 7 | // 8 | 9 | #include "HttpParserWrapper.h" 10 | #include "http_parser.h" 11 | 12 | CHttpParserWrapper* CHttpParserWrapper::m_instance = NULL; 13 | 14 | CHttpParserWrapper::CHttpParserWrapper() 15 | { 16 | 17 | } 18 | 19 | CHttpParserWrapper* CHttpParserWrapper::GetInstance() 20 | { 21 | if (!m_instance) { 22 | m_instance = new CHttpParserWrapper(); 23 | } 24 | 25 | return m_instance; 26 | } 27 | 28 | void CHttpParserWrapper::ParseHttpContent(const char* buf, uint32_t len) 29 | { 30 | http_parser_init(&m_http_parser, HTTP_REQUEST); 31 | memset(&m_settings, 0, sizeof(m_settings)); 32 | m_settings.on_url = OnUrl; 33 | m_settings.on_headers_complete = OnHeadersComplete; 34 | m_settings.on_body = OnBody; 35 | m_settings.on_message_complete = OnMessageComplete; 36 | 37 | m_read_all = false; 38 | m_total_length = 0; 39 | m_url.clear(); 40 | m_body_content.clear(); 41 | 42 | http_parser_execute(&m_http_parser, &m_settings, buf, len); 43 | } 44 | 45 | int CHttpParserWrapper::OnUrl(http_parser* parser, const char *at, size_t length) 46 | { 47 | m_instance->SetUrl(at, length); 48 | return 0; 49 | } 50 | 51 | int CHttpParserWrapper::OnHeadersComplete (http_parser* parser) 52 | { 53 | m_instance->SetTotalLength(parser->nread + (uint32_t)parser->content_length); 54 | return 0; 55 | } 56 | 57 | int CHttpParserWrapper::OnBody (http_parser* parser, const char *at, size_t length) 58 | { 59 | m_instance->SetBodyContent(at, length); 60 | return 0; 61 | } 62 | 63 | int CHttpParserWrapper::OnMessageComplete (http_parser* parser) 64 | { 65 | m_instance->SetReadAll(); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /cpp/src/msg_server/HttpParserWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // HttpPdu.h 3 | // http_msg_server 4 | // 5 | // Created by jianqing.du on 13-9-29. 6 | // Copyright (c) 2013年 ziteng. All rights reserved. 7 | // 8 | 9 | #ifndef http_msg_server_HttpParserWrapper_h 10 | #define http_msg_server_HttpParserWrapper_h 11 | 12 | #include "util.h" 13 | #include "http_parser.h" 14 | 15 | // extract url and content body from an ajax request 16 | class CHttpParserWrapper { 17 | public: 18 | virtual ~CHttpParserWrapper() {} 19 | 20 | static CHttpParserWrapper* GetInstance(); 21 | 22 | void ParseHttpContent(const char* buf, uint32_t len); 23 | 24 | bool IsReadAll() { return m_read_all; } 25 | uint32_t GetTotalLength() { return m_total_length; } 26 | string& GetUrl() { return m_url; } 27 | string& GetBodyContent() { return m_body_content; } 28 | 29 | void SetUrl(const char* url, size_t length) { m_url.append(url, length); } 30 | void SetBodyContent(const char* content, size_t length) { m_body_content.append(content, length); } 31 | void SetTotalLength(uint32_t total_len) { m_total_length = total_len; } 32 | void SetReadAll() { m_read_all = true; } 33 | 34 | static int OnUrl(http_parser* parser, const char *at, size_t length); 35 | static int OnHeadersComplete (http_parser* parser); 36 | static int OnBody (http_parser* parser, const char *at, size_t length); 37 | static int OnMessageComplete (http_parser* parser); 38 | private: 39 | CHttpParserWrapper(); 40 | 41 | private: 42 | static CHttpParserWrapper* m_instance; 43 | 44 | http_parser m_http_parser; 45 | http_parser_settings m_settings; 46 | 47 | bool m_read_all; 48 | uint32_t m_total_length; 49 | string m_url; 50 | string m_body_content; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /cpp/src/msg_server/HttpQuery.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpQuery.h 3 | * 4 | * Created on: 2013-10-22 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef HTTPQUERY_H_ 9 | #define HTTPQUERY_H_ 10 | 11 | #include "HttpConn.h" 12 | #include "jsonxx.h" 13 | 14 | class CHttpQuery 15 | { 16 | public: 17 | virtual ~CHttpQuery() {} 18 | 19 | static CHttpQuery* GetInstance(); 20 | 21 | static void DispatchQuery(std::string& url, std::string& post_data, CHttpConn* pHttpConn); 22 | private: 23 | CHttpQuery() {} 24 | 25 | static void _QueryCreateNormalGroup(jsonxx::Object& post_json_obj, CHttpConn* pHttpConn); 26 | static void _QueryChangeMember(jsonxx::Object& post_json_obj, CHttpConn* pHttpConn); 27 | private: 28 | static CHttpQuery* m_query_instance; 29 | }; 30 | 31 | string PackSendOk(); 32 | string URLDecode(const string &sIn); 33 | #endif /* HTTPQUERY_H_ */ 34 | -------------------------------------------------------------------------------- /cpp/src/msg_server/ImUser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ImUser.h 3 | * 4 | * Created on: 2014年4月16日 5 | * Author: ziteng 6 | */ 7 | 8 | #ifndef IMUSER_H_ 9 | #define IMUSER_H_ 10 | 11 | #include "imconn.h" 12 | 13 | #define MAX_ONLINE_FRIEND_CNT 100 //通知好友状态通知的最多个数 14 | 15 | class CMsgConn; 16 | 17 | class CImUser 18 | { 19 | public: 20 | CImUser(string user_name); 21 | ~CImUser(); 22 | 23 | uint32_t GetUserId() { return m_user_id; } 24 | string GetUserName() { return m_name; } 25 | bool IsValidate() { return m_bValidate; } 26 | void SetValidated() { m_bValidate = true; } 27 | uint32_t GetIMOnlineStatus() { return m_online_status; } 28 | 29 | void AddOnlineFriend(uint32_t friend_id) { 30 | if (m_online_friend_set.size() < MAX_ONLINE_FRIEND_CNT) 31 | m_online_friend_set.insert(friend_id); 32 | } 33 | 34 | void RemoveOnlineFriend(uint32_t friend_id) { 35 | m_online_friend_set.erase(friend_id); 36 | } 37 | 38 | bool IsMsgConnEmpty() { return m_conn_map.empty(); } 39 | void AddMsgConn(string token, CMsgConn* pMsgConn) { m_conn_map[token] = pMsgConn; } 40 | void DelMsgConn(string token) { m_conn_map.erase(token); } 41 | CMsgConn* GetMsgConn(string token); 42 | CMsgConn* GetMsgConnByHandle(uint32_t handle); 43 | void ValidateMsgConn(string token, CMsgConn*); 44 | 45 | void AddUnValidateMsgConn(CMsgConn* pMsgConn) { m_unvalidate_conn_set.insert(pMsgConn); } 46 | void DelUnValidateMsgConn(CMsgConn* pMsgConn) { m_unvalidate_conn_set.erase(pMsgConn); } 47 | CMsgConn* GetUnValidateMsgConn(uint32_t handle); 48 | 49 | 50 | user_conn_t GetUserConn(); 51 | void SetIMOnlineStatus(uint32_t status) { m_online_status = status; } 52 | void SetUser(user_info_t* user); 53 | void BroadcastPdu(CImPdu* pPdu, CMsgConn* pFromConn = NULL); 54 | void BroadcastPduWithOutMobile(CImPdu* pPdu, CMsgConn* pFromConn = NULL); 55 | void BroadcastClientMsgData(CImPduClientMsgData* pPdu, CMsgConn* pFromConn, uint32_t from_id); 56 | void BroadcastData(void* buff, uint32_t len, CMsgConn* pFromConn = NULL); 57 | 58 | void SendStatusChangeToFriend(uint32_t online_status); 59 | 60 | void HandleKickUser(CMsgConn* pConn); 61 | 62 | bool KickOutSameClientType(uint32_t client_type, CMsgConn* pFromConn = NULL); 63 | 64 | uint32_t GetClientTypeFlag(); 65 | private: 66 | uint32_t m_user_id; 67 | string m_name; 68 | string m_user_id_url; 69 | bool m_user_updated; 70 | uint32_t m_online_status; // 1-online, 2-off-line, 3-leave 71 | 72 | bool m_bValidate; 73 | 74 | set m_online_friend_set; 75 | map m_conn_map; 76 | set m_unvalidate_conn_set; 77 | //map 78 | }; 79 | 80 | typedef map ImUserMap_t; 81 | typedef map ImUserMapByName_t; 82 | 83 | class CImUserManager 84 | { 85 | public: 86 | CImUserManager() {} 87 | ~CImUserManager(); 88 | 89 | static CImUserManager* GetInstance(); 90 | CImUser* GetImUserById(uint32_t user_id); 91 | CImUser* GetImUserByName(string user_name); 92 | 93 | CMsgConn* GetMsgConnByHandle(uint32_t user_id, uint32_t handle); 94 | bool AddImUserByName(string user_name, CImUser* pUser); 95 | void RemoveImUserByName(string user_name); 96 | 97 | bool AddImUserById(uint32_t user_id, CImUser* pUser); 98 | void RemoveImUserById(uint32_t user_id); 99 | 100 | void RemoveImUser(CImUser* pUser); 101 | 102 | void RemoveAll(); 103 | void GetOnlineUserInfo(list* online_user_info); 104 | void GetUserConnCnt(list* user_conn_list, uint32_t& total_conn_cnt); 105 | 106 | void BroadcastPdu(CImPdu* pdu); 107 | private: 108 | ImUserMap_t m_im_user_map; 109 | ImUserMapByName_t m_im_user_map_by_name; 110 | }; 111 | 112 | #endif /* IMUSER_H_ */ 113 | -------------------------------------------------------------------------------- /cpp/src/msg_server/LoginServConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * LoginServConn.h 3 | * 4 | * Created on: 2013-7-8 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef LOGINSERVCONN_H_ 9 | #define LOGINSERVCONN_H_ 10 | 11 | #include "imconn.h" 12 | #include "ServInfo.h" 13 | 14 | class CLoginServConn : public CImConn 15 | { 16 | public: 17 | CLoginServConn(); 18 | virtual ~CLoginServConn(); 19 | 20 | bool IsOpen() { return m_bOpen; } 21 | 22 | void Connect(const char* server_ip, uint16_t server_port, uint32_t serv_idx); 23 | virtual void Close(); 24 | 25 | virtual void OnConfirm(); 26 | virtual void OnClose(); 27 | virtual void OnTimer(uint64_t curr_tick); 28 | 29 | virtual void HandlePdu(CImPdu* pPdu); 30 | private: 31 | bool m_bOpen; 32 | uint32_t m_serv_idx; 33 | }; 34 | 35 | void init_login_serv_conn(serv_info_t* server_list, uint32_t server_count, const char* msg_server_ip_addr1, 36 | const char* msg_server_ip_addr2, uint16_t msg_server_port, uint32_t max_conn_cnt); 37 | bool is_login_server_available(); 38 | void send_to_all_login_server(CImPdu* pPdu); 39 | 40 | 41 | #endif /* MSGCONN_LS_H_ */ 42 | -------------------------------------------------------------------------------- /cpp/src/msg_server/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INC = ../base 4 | OPT = -Wall -Wno-deprecated -g 5 | 6 | OBJS = FileServConn.o HttpParserWrapper.o HttpQuery.o http_parser.o HttpConn.o jsonxx.o ImUser.o AttachData.o GroupChat.o FileHandler.o MsgConn.o LoginServConn.o RouteServConn.o DBServConn.o msg_server.o ../base/libbase.a 7 | 8 | OS_NAME = $(shell uname) 9 | LC_OS_NAME = $(shell echo $(OS_NAME) | tr '[A-Z]' '[a-z]') 10 | ifeq ($(LC_OS_NAME), darwin) 11 | LIBS = -lpthread 12 | else 13 | LIBS = -lpthread -luuid 14 | endif 15 | 16 | SERVER = msg_server 17 | 18 | all: $(SERVER) 19 | 20 | $(SERVER): $(OBJS) 21 | $(CC) $(OPT) -o $@ $(OBJS) $(LIBS) 22 | 23 | GroupChat.o: GroupChat.cpp 24 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 25 | 26 | FileHandler.o: FileHandler.cpp 27 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 28 | 29 | MsgConn.o: MsgConn.cpp 30 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 31 | 32 | LoginServConn.o: LoginServConn.cpp 33 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 34 | 35 | RouteServConn.o: RouteServConn.cpp 36 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 37 | 38 | DBServConn.o: DBServConn.cpp 39 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 40 | 41 | msg_server.o: msg_server.cpp 42 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 43 | 44 | ImUser.o: ImUser.cpp 45 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 46 | 47 | AttachData.o: AttachData.cpp 48 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 49 | 50 | HttpQuery.o: HttpQuery.cpp 51 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 52 | 53 | http_parser.o: http_parser.c 54 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 55 | 56 | HttpConn.o: HttpConn.cpp 57 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 58 | 59 | HttpParserWrapper.o: HttpParserWrapper.cpp 60 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 61 | 62 | jsonxx.o: jsonxx.cpp 63 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 64 | 65 | FileServConn.o: FileServConn.cpp 66 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 67 | 68 | clean: 69 | rm -f $(SERVER) *.o 70 | checkos: 71 | @echo $(LC_OS_NAME) 72 | -------------------------------------------------------------------------------- /cpp/src/msg_server/MsgConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MsgConn.h 3 | * 4 | * Created on: 2013-7-5 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef MSGCONN_H_ 9 | #define MSGCONN_H_ 10 | 11 | #include "imconn.h" 12 | 13 | #define KICK_FROM_ROUTE_SERVER 1 14 | #define MAX_ONLINE_FRIEND_CNT 100 //通知好友状态通知的最多个数 15 | 16 | typedef struct { 17 | uint32_t seq_no; 18 | uint32_t from_id; 19 | uint64_t timestamp; 20 | } msg_ack_t; 21 | 22 | class CMsgConn : public CImConn 23 | { 24 | public: 25 | CMsgConn(); 26 | virtual ~CMsgConn(); 27 | 28 | string GetUserName() { return m_user_name; } 29 | uint32_t GetUserId(); 30 | uint32_t GetHandle() { return m_handle; } 31 | uint16_t GetPduVersion() { return m_pdu_version; } 32 | uint32_t GetClientType() { return m_client_type; } 33 | uint32_t GetClientTypeFlag(); 34 | void SetToken(string token) { m_token = token; } 35 | string GetToken() { return m_token; } 36 | void SetOpen() { m_bOpen = true; } 37 | bool IsOpen() { return m_bOpen; } 38 | void SendUserStatusUpdate(uint32_t user_status); 39 | 40 | virtual void Close(bool kick_user = false); 41 | 42 | virtual void OnConnect(net_handle_t handle); 43 | virtual void OnClose(); 44 | virtual inline void OnTimer(uint64_t curr_tick); 45 | 46 | virtual void HandlePdu(CImPdu* pPdu); 47 | 48 | void AddToSendList(uint32_t seq_no, uint32_t from_id); 49 | void DelFromSendList(uint32_t seq_no, uint32_t from_id); 50 | void SendUserActionLog(uint32_t action_type); 51 | private: 52 | void _HandleHeartBeat(CImPduHeartbeat* pPdu); 53 | void _HandleLoginRequest(CImPduLoginRequest* pPdu); 54 | void _HandleBuddyListRequest(CImPduClientBuddyListRequest* pPdu); 55 | void _HandleClientMsgData(CImPduClientMsgData* pPdu); 56 | void _HandleClientMsgDataAck(CImPduClientMsgDataAck* pPdu); 57 | void _HandleClientTimeRequest(CImPduClientTimeRequest* pPdu); 58 | void _HandleClientUnreadMsgCntRequest(CImPduClientUnreadMsgCntRequest* pPdu); 59 | void _HandleClientUnreadMsgRequest(CImPduClientUnreadMsgRequest* pPdu); 60 | void _HandleClientMsgReadAck(CImPduClientMsgReadAck* pPdu); 61 | void _HandleClientP2PCmdMsg(CImPduClientP2PCmdMsg* pPdu); 62 | void _HandleClientUserInfoRequest(CImPduClientUserInfoRequest* pPdu); 63 | void _HandleClientDBQueryRequest(CImPduClientDBQueryRequest* pPdu); 64 | 65 | void _HandleClientServiceSetting(CImPduClientServiceSetting* pPdu); 66 | void _HandleClientUserStatusRequest(CImPduClientUserStatusRequest* pPdu); 67 | void _HandleClientUsersStatusRequest(CImPduClientUsersStatusRequest* pPdu); 68 | 69 | void _HandleClientRemoveSessionRequest(CImPduClientRemoveSessionRequest* pPdu); 70 | void _HandleClientAllUserRequest(CImPduClientAllUserRequest* pPdu); 71 | 72 | void _HandleClientDepartmentRequest(CImPduClientDepartmentRequest* pPdu); 73 | private: 74 | string m_user_name; 75 | string m_token; 76 | bool m_bOpen; // only DB validate passed will be set to true; 77 | uint64_t m_login_time; 78 | 79 | uint32_t m_last_seq_no; 80 | 81 | uint16_t m_pdu_version; 82 | 83 | string m_client_version; // e.g MAC/2.2, or WIN/2.2 84 | 85 | list m_send_msg_list; 86 | 87 | uint32_t m_msg_cnt_per_sec; 88 | 89 | uint32_t m_client_type; //客户端登录方式 90 | }; 91 | 92 | void init_msg_conn(); 93 | 94 | #endif /* MSGCONN_H_ */ 95 | -------------------------------------------------------------------------------- /cpp/src/msg_server/RouteServConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * RouteServConn.h 3 | * 4 | * Created on: 2013-7-8 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef ROUTESERVCONN_H_ 9 | #define ROUTESERVCONN_H_ 10 | 11 | #include "imconn.h" 12 | #include "ServInfo.h" 13 | 14 | class CRouteServConn : public CImConn 15 | { 16 | public: 17 | CRouteServConn(); 18 | virtual ~CRouteServConn(); 19 | 20 | bool IsOpen() { return m_bOpen; } 21 | uint64_t GetConnectTime() { return m_connect_time; } 22 | 23 | void Connect(const char* server_ip, uint16_t server_port, uint32_t serv_idx); 24 | virtual void Close(); 25 | 26 | virtual void OnConfirm(); 27 | virtual void OnClose(); 28 | virtual void OnTimer(uint64_t curr_tick); 29 | 30 | virtual void HandlePdu(CImPdu* pPdu); 31 | private: 32 | void _HandleKickUser(CImPduServerKickUser* pPdu); 33 | void _HandleFriendStatusList(CImPduFriendStatusList* pPdu); 34 | void _HandleFriendStatusNotify(CImPduFriendStatusNotify* pPdu); 35 | void _HandleMsgData(CImPduMsgData* pPdu); 36 | void _HandleP2PMsg(CImPduP2PMsg* pPdu); 37 | void _HandleGroupP2PMsg(CImPduGroupP2PMessageResponse* pPdu); 38 | 39 | void _HandleUserStatusResponse(CImPduUserStatusResponse* pPdu); 40 | void _HandleUsersStatusResponse(CImPduUsersStatusResponse* pPdu); 41 | void _HandleUserClientTypeResponse(CImPduUserClientTypeResponse* pPdu); 42 | private: 43 | bool m_bOpen; 44 | uint32_t m_serv_idx; 45 | uint64_t m_connect_time; 46 | }; 47 | 48 | void init_route_serv_conn(serv_info_t* server_list, uint32_t server_count); 49 | bool is_route_server_available(); 50 | void send_to_all_route_server(CImPdu* pPdu); 51 | CRouteServConn* get_route_serv_conn(); 52 | 53 | 54 | #endif /* ROUTESERVCONN_H_ */ 55 | -------------------------------------------------------------------------------- /cpp/src/msg_server/msgserv_app.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // msg_serv_app.cpp 3 | // public_TTServer 4 | // 5 | // Created by luoning on 14-7-17. 6 | // Copyright (c) 2014年 luoning. All rights reserved. 7 | // 8 | 9 | #include "msg_serv_app.h" 10 | -------------------------------------------------------------------------------- /cpp/src/msg_server/msgserv_app.h: -------------------------------------------------------------------------------- 1 | // 2 | // msg_serv_app.h 3 | // public_TTServer 4 | // 5 | // Created by luoning on 14-7-17. 6 | // Copyright (c) 2014年 luoning. All rights reserved. 7 | // 8 | 9 | #ifndef __public_TTServer__msg_serv_app__ 10 | #define __public_TTServer__msg_serv_app__ 11 | 12 | #include 13 | 14 | #endif /* defined(__public_TTServer__msg_serv_app__) */ 15 | -------------------------------------------------------------------------------- /cpp/src/msg_server/msgserver.conf: -------------------------------------------------------------------------------- 1 | ListenIP=0.0.0.0 2 | ListenPort=8300 3 | 4 | HttpListenIP=0.0.0.0 5 | HttpListenPort=8400 6 | 7 | 8 | ConcurrentDBConnCnt=2 9 | DBServerIP1=127.0.0.1 10 | DBServerPort1=11000 11 | #DBServerIP2=127.0.0.1 12 | #DBServerPort2=11000 13 | 14 | LoginServerIP1=localhost 15 | LoginServerPort1=8100 16 | #LoginServerIP2=localhost 17 | #LoginServerPort2=8101 18 | 19 | RouteServerIP1=localhost 20 | RouteServerPort1=8200 21 | #RouteServerIP2=localhost 22 | #RouteServerPort2=8201 23 | 24 | FileServerIP1=localhost 25 | FileServerPort1=8500 26 | #FileServerIP2=localhost 27 | #FileServerPort2=8301 28 | 29 | IpAddr1=localhost #电信IP 30 | IpAddr2=localhost #网通IP 31 | MaxConnCnt=100000 32 | -------------------------------------------------------------------------------- /cpp/src/route_server/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INC = ../base 4 | OPT = -Wall -Wno-deprecated -g 5 | 6 | OBJS = RouteConn.o route_server.o ../base/libbase.a 7 | 8 | SERVER = route_server 9 | 10 | all: $(SERVER) 11 | 12 | $(SERVER): $(OBJS) 13 | $(CC) $(OPT) -o $@ $(OBJS) -lpthread 14 | 15 | 16 | RouteConn.o: RouteConn.cpp 17 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 18 | 19 | route_server.o: route_server.cpp 20 | $(CC) -I $(INC) $(OPT) -c -o $@ $< 21 | 22 | clean: 23 | rm -f $(SERVER) *.o 24 | 25 | -------------------------------------------------------------------------------- /cpp/src/route_server/RouteConn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * RouteConn.h 3 | * 4 | * Created on: 2013-7-4 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #ifndef ROUTECONN_H_ 9 | #define ROUTECONN_H_ 10 | 11 | #include "imconn.h" 12 | 13 | class CRouteConn : public CImConn 14 | { 15 | public: 16 | CRouteConn(); 17 | virtual ~CRouteConn(); 18 | 19 | virtual void Close(); 20 | 21 | virtual void OnConnect(net_handle_t handle); 22 | virtual void OnClose(); 23 | virtual void OnTimer(uint64_t curr_tick); 24 | 25 | virtual void HandlePdu(CImPdu* pPdu); 26 | 27 | private: 28 | void _HandleOnlineUserInfo(CImPduOnlineUserInfo* pPdu); 29 | void _HandleUserStatusUpdate(CImPduUserStatusUpdate* pPdu); 30 | void _HandleFriendStatusQuery(CImPduFriendStatusQuery* pPdu); 31 | void _HandleFriendStatusNotify(CImPduFriendStatusNotify* pPdu); 32 | void _HandleMsgData(CImPduMsgData* pPdu); 33 | void _HandleP2PMsg(CImPduP2PMsg* pPdu); 34 | void _HandleRoleSet(CImPduRoleSet* pPdu); 35 | void _HandleUserStatusRequest(CImPduUserStatusRequest* pPdu); 36 | void _HandleUsersStatusRequest(CImPduUsersStatusRequest* pPdu); 37 | void _HandleKickOut(CImPduServerKickUser* pPdu); 38 | void _HandleUserClientType(CImPduUserClientTypeRequest * pPdu); 39 | void _HandleFileNotify(CImPduFileNotify* pPdu); 40 | 41 | void _UpdateUserStatus(uint32_t user_id, uint32_t status, uint32_t client_type_flag); 42 | void _BroadcastMsg(CImPdu* pPdu); 43 | void _DeliverMsgData(uint32_t from_id, uint32_t to_id, CImPdu* pPdu); 44 | private: 45 | list m_notify_user_list; 46 | bool m_bMaster; 47 | }; 48 | 49 | void init_routeconn_timer_callback(); 50 | 51 | #endif /* ROUTECONN_H_ */ 52 | -------------------------------------------------------------------------------- /cpp/src/route_server/route_server.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * route_server.cpp 3 | * 4 | * Created on: 2013-7-4 5 | * Author: ziteng@mogujie.com 6 | */ 7 | 8 | #include "RouteConn.h" 9 | #include "netlib.h" 10 | #include "ConfigFileReader.h" 11 | #include "version.h" 12 | 13 | // this callback will be replaced by imconn_callback() in OnConnect() 14 | void route_serv_callback(void* callback_data, uint8_t msg, uint32_t handle, void* pParam) 15 | { 16 | if (msg == NETLIB_MSG_CONNECT) 17 | { 18 | CRouteConn* pConn = new CRouteConn(); 19 | pConn->OnConnect(handle); 20 | } 21 | else 22 | { 23 | log("!!!error msg: %d\n", msg); 24 | } 25 | } 26 | 27 | int main(int argc, char* argv[]) 28 | { 29 | if ((argc == 2) && (strcmp(argv[1], "-v") == 0)) { 30 | printf("Server Version: RouteServer/%s\n", VERSION); 31 | printf("Server Build: %s %s\n", __DATE__, __TIME__); 32 | return 0; 33 | } 34 | 35 | signal(SIGPIPE, SIG_IGN); 36 | srand(time(NULL)); 37 | 38 | CConfigFileReader config_file("routeserver.conf"); 39 | 40 | char* listen_ip = config_file.GetConfigName("ListenIP"); 41 | char* str_listen_msg_port = config_file.GetConfigName("ListenMsgPort"); 42 | 43 | if (!listen_ip || !str_listen_msg_port) { 44 | log("config item missing, exit...\n"); 45 | return -1; 46 | } 47 | 48 | uint16_t listen_msg_port = atoi(str_listen_msg_port); 49 | 50 | int ret = netlib_init(); 51 | 52 | if (ret == NETLIB_ERROR) 53 | return ret; 54 | 55 | CStrExplode listen_ip_list(listen_ip, ';'); 56 | for (uint32_t i = 0; i < listen_ip_list.GetItemCnt(); i++) { 57 | ret = netlib_listen(listen_ip_list.GetItem(i), listen_msg_port, route_serv_callback, NULL); 58 | if (ret == NETLIB_ERROR) 59 | return ret; 60 | } 61 | 62 | printf("server start listen on: %s:%d\n", listen_ip, listen_msg_port); 63 | 64 | init_routeconn_timer_callback(); 65 | 66 | printf("now enter the event loop...\n"); 67 | 68 | netlib_eventloop(); 69 | 70 | return 0; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /cpp/src/route_server/routeserver.conf: -------------------------------------------------------------------------------- 1 | ListenIP=0.0.0.0 # Listening IP 2 | ListenMsgPort=8200 # Listening Port for MsgServer 3 | -------------------------------------------------------------------------------- /cpp/src/tools/Makefile: -------------------------------------------------------------------------------- 1 | daeml: daeml.cpp 2 | g++ -Wall -o daeml daeml.cpp 3 | -------------------------------------------------------------------------------- /cpp/src/tools/daeml.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void CloseAll(int fd) 10 | { 11 | int fd_limit = sysconf(_SC_OPEN_MAX); 12 | 13 | while (fd < fd_limit) 14 | { 15 | close(fd++); 16 | } 17 | } 18 | 19 | int Daemon(int no_chdir, int no_close, int root) 20 | { 21 | switch (fork()) 22 | { 23 | case 0: 24 | break; 25 | case -1: 26 | return -1; 27 | default: 28 | _exit(0); 29 | } 30 | 31 | if (setsid() < 0) 32 | { 33 | return -1; 34 | } 35 | if (!root && (setuid(1) < 0)) 36 | { 37 | return -1; 38 | } 39 | 40 | switch (fork()) 41 | { 42 | case 0: 43 | break; 44 | case -1: 45 | return -1; 46 | default: 47 | _exit(0); 48 | } 49 | 50 | if (!no_chdir) 51 | { 52 | chdir("/"); 53 | } 54 | 55 | if (!no_close) 56 | { 57 | CloseAll(0); 58 | dup(0); 59 | dup(0); 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | #define PRINT(a) a 66 | void PrintUsage(char* name) 67 | { 68 | printf ( 69 | PRINT("\n ----- \n\n") 70 | PRINT("Usage:\n") 71 | PRINT(" %s program_name \n\n") 72 | PRINT("Where:\n") 73 | PRINT(" %s - Name of this Daemon loader.\n") 74 | PRINT(" program_name - Name (including path) of the program you want to load as daemon.\n\n") 75 | PRINT("Example:\n") 76 | PRINT(" %s ./atprcmgr - Launch program 'atprcmgr' in current directory as daemon. \n\n\n\n"), 77 | name, name, name 78 | ); 79 | } 80 | 81 | int main(int argc, char* argv[]) 82 | { 83 | printf( 84 | PRINT("\n") 85 | PRINT("Daemon loader\n") 86 | PRINT("Launch specified program as daemon.\n") 87 | ); 88 | 89 | if (argc < 2) 90 | { 91 | printf("Missing parameter: daemon program name not specified!\n"); 92 | PrintUsage(argv[0]); 93 | return 0; 94 | } 95 | 96 | printf("Loading %s as daemon, please wait...\n\n\n", argv[1]); 97 | 98 | if (Daemon(1, 0, 1) >= 0) 99 | { 100 | signal(SIGCHLD, SIG_IGN); 101 | execv(argv[1], argv + 1); 102 | printf("Excute daemon programm %s failed.\n", argv[1]); 103 | return 0; 104 | } 105 | 106 | printf("Create daemon failed. Please check if you have 'root' privilege.\n"); 107 | return 0; 108 | } 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/pics/server.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lizj3624/https-github.com-mogutt-TTServer/46e7665c6a36a577d637830bf04b78862dfd5b75/docs/pics/server.jpg -------------------------------------------------------------------------------- /docs/protocol/TT_Client_protocol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lizj3624/https-github.com-mogutt-TTServer/46e7665c6a36a577d637830bf04b78862dfd5b75/docs/protocol/TT_Client_protocol.pdf -------------------------------------------------------------------------------- /java/src/main/bin/packagedev.sh: -------------------------------------------------------------------------------- 1 | mvn clean package -Dmaven.test.skip=true 2 | mvn dependency:copy-dependencies 3 | -------------------------------------------------------------------------------- /java/src/main/bin/packageproduct.sh: -------------------------------------------------------------------------------- 1 | mvn clean package -P product -Dmaven.test.skip=true 2 | mvn dependency:copy-dependencies 3 | -------------------------------------------------------------------------------- /java/src/main/bin/run.sh: -------------------------------------------------------------------------------- 1 | java -server -Djava.ext.dirs=./ -Xmx2048M -Xms2048M -Xmn128M -XX:PermSize=64m -XX:MaxPermSize=128m -XX:+UseCompressedOops -XX:+UseParallelOldGC -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCDetails -Xloggc:/tmp/mogutalk-gc.log -XX:+HeapDumpOnOutOfMemoryError -Djava.io.tmpdir=/tmp -XX:HeapDumpPath=/tmp/oom.heapdump -jar ./mogutalk-business-0.0.1-SNAPSHOT.jar $1 > mogutalk.log & 2 | echo $! > ./mogutalk.pid 3 | -------------------------------------------------------------------------------- /java/src/main/bin/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | t=`date +%Y%m%d_%H%M%S` 4 | cp src/main/bin/* ./ 5 | ALLPROTS=($@) 6 | for port in ${ALLPROTS[@]} 7 | do 8 | file="./${port}" 9 | if [ -d "$file" ] ; then 10 | if [ ! -d "backup" ] ; then 11 | mkdir "backup" 12 | fi 13 | bak="backup/${port}_${t}" 14 | mv $file $bak 15 | fi 16 | mkdir $port 17 | cd $port 18 | cp ../target/mogutalk-business-0.0.1-SNAPSHOT.jar ./ 19 | cp ../run.sh ./ 20 | sh run.sh $port 21 | cd ../ 22 | done 23 | -------------------------------------------------------------------------------- /java/src/main/bin/talkshutdown.sh: -------------------------------------------------------------------------------- 1 | echo stop > /tmp/.mogutalk_stop.tmp 2 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/MainServer.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares; 2 | 3 | import com.mogujie.ares.configure.SysConstants; 4 | import com.mogujie.ares.extend.action.DelayUpdateMonitor; 5 | import com.mogujie.ares.lib.logger.Logger; 6 | import com.mogujie.ares.lib.logger.LoggerFactory; 7 | import com.mogujie.ares.manager.CacheManager; 8 | import com.mogujie.ares.manager.ConfigureManager; 9 | import com.mogujie.ares.manager.DBManager; 10 | import com.mogujie.ares.manager.ElegantStopManager; 11 | import com.mogujie.ares.manager.NetworkManager; 12 | import com.mogujie.ares.manager.TimerManager; 13 | 14 | /** 15 | * 初始化阿瑞斯项目main类 16 | * @author ziye 17 | * 18 | */ 19 | public class MainServer { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(MainServer.class); 22 | 23 | public MainServer() { 24 | 25 | } 26 | 27 | public void bootup(int port) { 28 | try { 29 | initLog(); 30 | initConfigure(); 31 | initBase(); // 基础部分的启动,包括各种连接池 32 | initTimers(); 33 | initNet(port); 34 | startStopChecker(port); 35 | } catch (Exception e) { 36 | logger.error("", e); 37 | ElegantStopManager.getInstance(port).shutdown(); 38 | } 39 | } 40 | 41 | /** 42 | * 日志初始化 43 | */ 44 | public void initLog() { 45 | // 这里好像没什么好做的... 46 | } 47 | 48 | /** 49 | * 配置相关的初始化 50 | * @throws Exception 51 | */ 52 | public void initConfigure() throws Exception { 53 | ConfigureManager.getInstance().loadAllConfigs(); 54 | } 55 | 56 | /** 57 | * 包括lib内的连接池等的初始化 58 | * @throws Exception 59 | */ 60 | public void initBase() throws Exception { 61 | DBManager dbManager = DBManager.getInstance(); 62 | CacheManager cacheManager = CacheManager.getInstance(); 63 | if(dbManager == null || cacheManager == null) { 64 | throw new Exception("初始化db和cache连接池出错!"); 65 | } 66 | } 67 | 68 | /** 69 | * 网络初始化 70 | * @throws Exception 71 | */ 72 | public void initNet(int port) throws Exception { 73 | NetworkManager networkManager = NetworkManager.getInstance(); 74 | networkManager.init(port); 75 | } 76 | 77 | /** 78 | * 定时脚本启动 79 | * @throws Exception 80 | */ 81 | public void initTimers() throws Exception { 82 | TimerManager.getInstance().lanuch(); 83 | DelayUpdateMonitor.getInstance().start(); 84 | } 85 | 86 | /** 87 | * 启动结束Check是否结束程序的线程 88 | */ 89 | public void startStopChecker(int port) { 90 | ElegantStopManager.getInstance(port).startCheckShutdownThread(); 91 | } 92 | 93 | public static void main( String[] args ) { 94 | int port = SysConstants.SERVER_DEFAULT_PORT; 95 | if(args.length >= 1) { 96 | port = Integer.parseInt(args[0]); 97 | } 98 | MainServer server = new MainServer(); 99 | server.bootup(port); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/configure/BizConstants.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.configure; 2 | 3 | /** 4 | * 5 | * @Description: 业务相关的常量定义 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2013-9-7 下午1:11:34 8 | * 9 | */ 10 | public class BizConstants { 11 | 12 | // 默认的serviceId 13 | public static final int DEFAULT_SERVICEID = 7; // 与C++端通信的ID 14 | 15 | // ---------------- 消息类型的常量定义 ------------------ 16 | 17 | public static final int COMMANDID_HEARTBEAT = 1; // 心跳包的commandId 18 | 19 | public static final int COMMANDID_STOP_RECEIVE = 100; // 停止的commandId 20 | 21 | public static final int COMMANDID_SEND_MESSAGE = 111; // 发送消息的commandId 22 | 23 | // ---------------- 用户角色定义 ---------------- 24 | 25 | public static final int ROLE_NORMAL_USER = 0; // normal user 26 | 27 | public static final int ROLE_SERVICE_USER = 1; // admin user 28 | 29 | // ---------------- 用户信息默认值 --------------- 30 | 31 | public static final String USER_INFO_DEFAULT_AVATAR = "/avatar/avatar_default.jpg"; // 默认用户头像 32 | 33 | public static final String GROUP_INFO_DEFAULT_AVATAR = "/avatar/group_avatar_default.jpg"; // 默认群组头像 34 | 35 | // ---------------- 消息 ------------------- 36 | // 消息里图片的占位符 37 | public static final String MESSAGE_IMAGE_PREFIX = "&$#@~^@[{:"; 38 | public static final String MESSAGE_IMAGE_SUFFIX = ":}]&$~@#@"; 39 | public static final String Message_IMAGE_URL_REGEX = "(http://)?s\\d{1,2}"; 40 | public static final String MESSAGE_IMAGE_FULL_PLACEHOLDER_REGEX = "(&\\$#@~\\^@\\[\\{:)" 41 | + "((http[s]?://)?s\\d{1,2}\\.mogujie\\.(com|cn))(/pic/\\d{6}/[0-9a-z_]{30,40}\\d{1,10}x\\d{1,10}.*" 42 | + ":\\}\\]&\\$~@#@)"; // 图片占位符的正则表达式 43 | public static final String MESSAGE_IMAGE_PART_PLACEHOLDER_REGEX = "(&\\$#@~\\^@\\[\\{:)" 44 | + "(/pic/\\d{6}/[0-9a-z_]{30,40}\\d{1,10}x\\d{1,10}.*" 45 | + ":\\}\\]&\\$~@#@)"; // 图片占位符的正则表达式 46 | 47 | // ------------ IM消息的type ------------ 48 | public static final int MESSAGE_TYPE_IM = 0x01; // 普通用户+系统消息 49 | public static final int MESSAGE_TYPE_IM_GROUP = 0x11; 50 | public static final int MESSAGE_TYPE_IM_AUDIO = 0x02; 51 | public static final int MESSAGE_TYPE_IM_GROUP_AUDIO = 0x12; 52 | 53 | // 群组 54 | public static final String GROUP_TOTAL_MSG_COUNTER_REDIS_KEY_SUFFIX = "_group_msg"; // GROUP_TOTAL_MSG_COUNTER_REDIS_KEY_SUFFIX 55 | 56 | // {userId} + "_" + {groupId} + GROUP_USER_MSG_COUNTER_REDIS_KEY_SUFFIX 57 | public static final String GROUP_USER_MSG_COUNTER_REDIS_KEY_SUFFIX = "_user_group"; 58 | 59 | // hashtable里的两个subkey 60 | public static final String GROUP_COUNTER_SUBKEY_COUNTER = "count"; 61 | public static final String GROUP_COUNTER_SUBKEY_LASTID = "lastId"; 62 | 63 | public static final int GROUP_UNREAD_MAX_COUNTER = 150; // 用户一次读取未读群消息不能超过200 64 | 65 | public static final int GROUP_TYPE_FIXED = 1; 66 | 67 | public static final int GROUP_TYPE_TEMP = 2; 68 | 69 | public static final int UNREAD_MAX_COUNTER = 100; // 用户一次读取未读消息不能超过100 70 | 71 | // ------------- 服务号小T --------------- 72 | public static final int SYS_SERVER_USER_ID = 10000; 73 | public static final String SYS_SERVER_USER_NAME = "小T"; 74 | 75 | } 76 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/configure/SysConstants.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.configure; 2 | 3 | 4 | public class SysConstants { 5 | 6 | // 服务器的默认端口,可以通过启动时的args来修改 7 | public static final int SERVER_DEFAULT_PORT = 11000; 8 | 9 | // 默认消息头的长度 10 | public static final int PROTOCOL_HEADER_LENGTH = 12; 11 | 12 | //packet的当前版本号,最新版本 13 | public static final int PROTOCOL_CURRENT_VERSION = 2; 14 | 15 | public static final int PROTOCOL_PREVIOUS_VERSION=1; //上一版本的版本号 16 | 17 | // 定时任务启动状态 18 | public static final String TASK_ENABLE_RUN = "1"; 19 | 20 | // 定时任务停止状态 21 | public static final String TASK_DISENABLE_RUN = "0"; 22 | 23 | //停止应用的检查时间 24 | public static final long CHECK_STOP_GAP_TIME = 2000; 25 | 26 | //停止实例配置文件 27 | public static final String ELEGANT_STOP_FILE = "/tmp/.mogutalk_stop"; 28 | 29 | public static final String ELEGANT_SHUTDOWN_SHELL_SCRIPT = "mogutalkshutdown"; 30 | 31 | //停止实例值 32 | public static final String ELEGANT_STOP_CONTENT = "stop"; 33 | 34 | // --------------- redis pool --------------- 35 | 36 | // 从数据库连接池中取得连接时,对其的有效性进行检查 37 | public static final boolean TEST_ON_BORROW = true; 38 | 39 | // 最大连接数 40 | public static final int MAX_ACTIVE = 36; 41 | 42 | // 最大闲置的连接数 43 | public static final int MAX_IDLE = 20; 44 | 45 | // 最小..... 46 | public static final int MIN_IDLE = 5; 47 | 48 | // 请求最长等待时间/毫秒 49 | public static final int MAX_WAIT = 1000; 50 | 51 | // 闲置时测试 52 | public static final boolean TEST_WHILE_IDLE = true; 53 | 54 | // redis db的名字 55 | public static final String REDIS_INSTANCE_NAME_COUNTER = "counter"; // 总消息计数器 56 | 57 | public static final String REDIS_INSTANCE_NAME_SESSION = "session"; // mogujie session 58 | 59 | public static final String REDIS_INSTANCE_NAME_UNREAD = "unread"; // 未读消息计数 60 | 61 | public static final String REDIS_CINFO_PREFIX_KEY="user_c_"; //redis cinfo的前缀key. 62 | 63 | public static final String REDIS_CINFO_SUB_KEY="chatNew"; //redis cinfo 子key 64 | 65 | // --------------- db pool ----------------- 66 | 67 | public static final int DB_MIN_CONNECTIONS_PER_PARTITION = 10; 68 | 69 | public static final int DB_MAX_CONNECTIONS_PER_PARTITION = 18; 70 | 71 | public static final int DB_IDLE_CONNECTION_TEST_PERIOD = 60; 72 | 73 | public static final int DB_PARTITION_COUNT = 1; 74 | } 75 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/Audio.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | public class Audio { 4 | 5 | private int id; 6 | 7 | private int userId; 8 | 9 | private int toUserId; 10 | 11 | private String path; 12 | 13 | private int fileSize; 14 | 15 | private int costTime; 16 | 17 | private int created; 18 | 19 | private byte[] data; 20 | 21 | public int getId() { 22 | return id; 23 | } 24 | 25 | public void setId(int id) { 26 | this.id = id; 27 | } 28 | 29 | public String getPath() { 30 | return path; 31 | } 32 | 33 | public void setPath(String path) { 34 | this.path = path; 35 | } 36 | 37 | public int getUserId() { 38 | return userId; 39 | } 40 | 41 | public void setUserId(int userId) { 42 | this.userId = userId; 43 | } 44 | 45 | public int getToUserId() { 46 | return toUserId; 47 | } 48 | 49 | public void setToUserId(int toUserId) { 50 | this.toUserId = toUserId; 51 | } 52 | 53 | public int getFileSize() { 54 | return fileSize; 55 | } 56 | 57 | public void setFileSize(int fileSize) { 58 | this.fileSize = fileSize; 59 | } 60 | 61 | public int getCostTime() { 62 | return costTime; 63 | } 64 | 65 | public void setCostTime(int costTime) { 66 | this.costTime = costTime; 67 | } 68 | 69 | public int getCreated() { 70 | return created; 71 | } 72 | 73 | public void setCreated(int created) { 74 | this.created = created; 75 | } 76 | 77 | public byte[] getData() { 78 | return data; 79 | } 80 | 81 | public void setData(byte[] data) { 82 | this.data = data; 83 | } 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/ClientType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.mogujie.ares.data; 5 | 6 | /** 7 | * @author seishuchen 8 | * @email shallowgrave@126.com 9 | */ 10 | public enum ClientType { 11 | WINDOWS(1), MAC(2), IOS(17), ANDROID(18); 12 | private int value; 13 | 14 | ClientType(int value) { 15 | this.value = value; 16 | } 17 | 18 | public int getValue() { 19 | return value; 20 | } 21 | 22 | public void setValue(int value) { 23 | this.value = value; 24 | } 25 | 26 | public static ClientType valueOf(int value) { 27 | switch (value) { 28 | case 1: 29 | return WINDOWS; 30 | case 2: 31 | return MAC; 32 | case 17: 33 | return IOS; 34 | case 18: 35 | return ANDROID; 36 | default: 37 | return MAC; 38 | } 39 | } 40 | 41 | /** 42 | * 获得客户端类型缓存Key前缀 43 | * @param value 44 | * @return 45 | */ 46 | public static String prefixKeyOf(int value) { 47 | switch (value) { 48 | case 17: 49 | return "IOS"; 50 | case 18: 51 | return "ANDROID"; 52 | default: 53 | return ""; 54 | } 55 | } 56 | 57 | public static String prefixKeyOf(ClientType clientType) { 58 | return prefixKeyOf(clientType.value); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/Counter.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 7 | * @ClassName: Counter 8 | * @Description: 计数器描述类 9 | * @author shitou - shitou(at)mogujie.com 10 | * @date 2013-7-20 下午5:52:24 11 | * 12 | */ 13 | public class Counter 14 | { 15 | 16 | public int userId; 17 | 18 | public Map unreadCount; 19 | 20 | public Map msgCount; 21 | 22 | public void setUserId(int setUserId) 23 | { 24 | userId = setUserId; 25 | } 26 | 27 | public int getUserId() 28 | { 29 | return userId; 30 | } 31 | 32 | public void setUnreadCount(MapunreadMap) 33 | { 34 | unreadCount = unreadMap; 35 | } 36 | 37 | public Map getUnreadCount() 38 | { 39 | return unreadCount; 40 | } 41 | 42 | public void setMsgCount(MapsetMsgCount) 43 | { 44 | msgCount = setMsgCount; 45 | } 46 | 47 | public Map getMsgCount() 48 | { 49 | return msgCount; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/Department.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | public class Department { 4 | 5 | protected int departId; // 部门id 6 | 7 | // protected String departName; // 部门名 8 | 9 | protected String title; // 部门标题 10 | 11 | protected String description; // 部门描述 12 | 13 | protected int parentDepartId; // 父部门id(上级部门id) 14 | 15 | protected int leader; // 部门leader 16 | 17 | protected int status; // 部门状态 0:正常 1:删除 18 | 19 | private int created; // 创建时间 20 | 21 | private int updated; // 更新时间 22 | 23 | public int getDepartId() { 24 | return departId; 25 | } 26 | 27 | public void setDepartId(int departId) { 28 | this.departId = departId; 29 | } 30 | 31 | // public String getDepartName() { 32 | // return departName; 33 | // } 34 | // 35 | // public void setDepartName(String departName) { 36 | // this.departName = departName; 37 | // } 38 | 39 | public String getTitle() { 40 | return title; 41 | } 42 | 43 | public void setTitle(String title) { 44 | this.title = title; 45 | } 46 | 47 | public String getDescription() { 48 | return description; 49 | } 50 | 51 | public void setDescription(String description) { 52 | this.description = description; 53 | } 54 | 55 | public int getParentDepartId() { 56 | return parentDepartId; 57 | } 58 | 59 | public void setParentDepartId(int parentDepartId) { 60 | this.parentDepartId = parentDepartId; 61 | } 62 | 63 | public int getLeader() { 64 | return leader; 65 | } 66 | 67 | public void setLeader(int leader) { 68 | this.leader = leader; 69 | } 70 | 71 | public int getStatus() { 72 | return status; 73 | } 74 | 75 | public void setStatus(int status) { 76 | this.status = status; 77 | } 78 | 79 | public int getCreated() { 80 | return created; 81 | } 82 | 83 | public void setCreated(int created) { 84 | this.created = created; 85 | } 86 | 87 | public int getUpdated() { 88 | return updated; 89 | } 90 | 91 | public void setUpdated(int updated) { 92 | this.updated = updated; 93 | } 94 | 95 | public Department() { 96 | // TODO Auto-generated constructor stub 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/Group.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 7 | * @Description: 群信息 8 | * @author ziye - ziye[at]mogujie.com 9 | * @date 2014-1-5 下午4:17:55 10 | * 11 | */ 12 | public class Group { 13 | 14 | private int groupId; // 群Id 15 | 16 | private String groupName = ""; // 群名 17 | 18 | private String avatar = ""; // 群头像 19 | 20 | private String adesc = ""; // 群描述 21 | 22 | private int createUserId; // 创建者Id 23 | 24 | private int groupType; // 群类型 1:固定群 2:临时群 25 | 26 | private int status; // 群状态 1:正常 0: 删除 27 | 28 | private int memberCnt; // 群成员个数 29 | 30 | private List userIdList; 31 | 32 | private int updated; // 群信息更新时间 33 | 34 | private int created; // 群创建时间 35 | 36 | public int getGroupId() { 37 | return groupId; 38 | } 39 | 40 | public void setGroupId(int groupId) { 41 | this.groupId = groupId; 42 | } 43 | 44 | public String getGroupName() { 45 | return groupName; 46 | } 47 | 48 | public void setGroupName(String groupName) { 49 | this.groupName = groupName; 50 | } 51 | 52 | public String getAvatar() { 53 | return avatar; 54 | } 55 | 56 | public void setAvatar(String avatar) { 57 | this.avatar = avatar; 58 | } 59 | 60 | public String getAdesc() { 61 | return adesc; 62 | } 63 | 64 | public void setAdesc(String adesc) { 65 | this.adesc = adesc; 66 | } 67 | 68 | public int getCreateUserId() { 69 | return createUserId; 70 | } 71 | 72 | public void setCreateUserId(int createUserId) { 73 | this.createUserId = createUserId; 74 | } 75 | 76 | public int getGroupType() { 77 | return groupType; 78 | } 79 | 80 | public void setGroupType(int groupType) { 81 | this.groupType = groupType; 82 | } 83 | 84 | public int getMemberCnt() { 85 | return memberCnt; 86 | } 87 | 88 | public void setMemberCnt(int memberCnt) { 89 | this.memberCnt = memberCnt; 90 | } 91 | 92 | public int getStatus() { 93 | return status; 94 | } 95 | 96 | public void setStatus(int status) { 97 | this.status = status; 98 | } 99 | 100 | public int getUpdated() { 101 | return updated; 102 | } 103 | 104 | public void setUpdated(int updated) { 105 | this.updated = updated; 106 | } 107 | 108 | public int getCreated() { 109 | return created; 110 | } 111 | 112 | public void setCreated(int created) { 113 | this.created = created; 114 | } 115 | 116 | public List getUserIdList() { 117 | return userIdList; 118 | } 119 | 120 | public void setUserIdList(List userIdList) { 121 | this.userIdList = userIdList; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/GroupCounterItem.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | public class GroupCounterItem { 4 | 5 | private int userId; 6 | 7 | private int groupId; 8 | 9 | private int groupTotalCount; // 群总消息数 10 | 11 | private int userUnreadCount; // 用户在该群中的未读消息数 12 | 13 | private int lastMessageId; 14 | 15 | public int getUserId() { 16 | return userId; 17 | } 18 | 19 | public void setUserId(int userId) { 20 | this.userId = userId; 21 | } 22 | 23 | public int getGroupId() { 24 | return groupId; 25 | } 26 | 27 | public void setGroupId(int groupId) { 28 | this.groupId = groupId; 29 | } 30 | 31 | public int getGroupTotalCount() { 32 | return groupTotalCount; 33 | } 34 | 35 | public void setGroupTotalCount(int groupTotalCount) { 36 | this.groupTotalCount = groupTotalCount; 37 | } 38 | 39 | public int getUserUnreadCount() { 40 | return userUnreadCount; 41 | } 42 | 43 | public void setUserUnreadCount(int userUnreadCount) { 44 | this.userUnreadCount = userUnreadCount; 45 | } 46 | 47 | public int getLastMessageId() { 48 | return lastMessageId; 49 | } 50 | 51 | public void setLastMessageId(int lastMessageId) { 52 | this.lastMessageId = lastMessageId; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/GroupMessage.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | public class GroupMessage { 4 | 5 | 6 | // 消息id 7 | private int id; 8 | 9 | private int userId; 10 | 11 | private User userInfo; 12 | 13 | private int groupId; 14 | 15 | private Group groupInfo; 16 | 17 | private String content; 18 | 19 | /** 20 | * @return the audio 21 | */ 22 | public Audio getAudio() { 23 | return audio; 24 | } 25 | 26 | /** 27 | * @param audio the audio to set 28 | */ 29 | public void setAudio(Audio audio) { 30 | this.audio = audio; 31 | } 32 | 33 | private Audio audio; 34 | 35 | private int status; 36 | 37 | private int updated; 38 | 39 | /** 40 | * @return the messageType 41 | */ 42 | public int getMessageType() { 43 | return messageType; 44 | } 45 | 46 | /** 47 | * @param messageType the messageType to set 48 | */ 49 | public void setMessageType(int messageType) { 50 | this.messageType = messageType; 51 | } 52 | 53 | private int created; 54 | 55 | private int messageType; 56 | 57 | public int getId() { 58 | return id; 59 | } 60 | 61 | public void setId(int id) { 62 | this.id = id; 63 | } 64 | 65 | public int getUserId() { 66 | return userId; 67 | } 68 | 69 | public void setUserId(int userId) { 70 | this.userId = userId; 71 | } 72 | 73 | public User getUserInfo() { 74 | return userInfo; 75 | } 76 | 77 | public void setUserInfo(User userInfo) { 78 | this.userInfo = userInfo; 79 | } 80 | 81 | public int getGroupId() { 82 | return groupId; 83 | } 84 | 85 | public void setGroupId(int groupId) { 86 | this.groupId = groupId; 87 | } 88 | 89 | public Group getGroupInfo() { 90 | return groupInfo; 91 | } 92 | 93 | public void setGroupInfo(Group groupInfo) { 94 | this.groupInfo = groupInfo; 95 | } 96 | 97 | public String getContent() { 98 | return content; 99 | } 100 | 101 | public void setContent(String content) { 102 | this.content = content; 103 | } 104 | 105 | public int getStatus() { 106 | return status; 107 | } 108 | 109 | public void setStatus(int status) { 110 | this.status = status; 111 | } 112 | 113 | public int getUpdated() { 114 | return updated; 115 | } 116 | 117 | public void setUpdated(int updated) { 118 | this.updated = updated; 119 | } 120 | 121 | public int getCreated() { 122 | return created; 123 | } 124 | 125 | public void setCreated(int created) { 126 | this.created = created; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/GroupRelation.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | /** 4 | * 5 | * @Description: 群-用户关系 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2014-1-5 下午4:17:37 8 | * 9 | */ 10 | public class GroupRelation { 11 | 12 | private int id; 13 | 14 | private int groupId; 15 | 16 | private int userId; 17 | 18 | private int title; 19 | 20 | private int groupType; 21 | 22 | private int status; 23 | 24 | private int created; 25 | 26 | private int updated; 27 | 28 | public int getId() { 29 | return id; 30 | } 31 | 32 | public void setId(int id) { 33 | this.id = id; 34 | } 35 | 36 | public int getGroupId() { 37 | return groupId; 38 | } 39 | 40 | public void setGroupId(int groupId) { 41 | this.groupId = groupId; 42 | } 43 | 44 | public int getUserId() { 45 | return userId; 46 | } 47 | 48 | public void setUserId(int userId) { 49 | this.userId = userId; 50 | } 51 | 52 | public int getTitle() { 53 | return title; 54 | } 55 | 56 | public void setTitle(int title) { 57 | this.title = title; 58 | } 59 | 60 | public int getGroupType() { 61 | return groupType; 62 | } 63 | 64 | public void setGroupType(int groupType) { 65 | this.groupType = groupType; 66 | } 67 | 68 | public int getStatus() { 69 | return status; 70 | } 71 | 72 | public void setStatus(int status) { 73 | this.status = status; 74 | } 75 | 76 | public int getCreated() { 77 | return created; 78 | } 79 | 80 | public void setCreated(int created) { 81 | this.created = created; 82 | } 83 | 84 | public int getUpdated() { 85 | return updated; 86 | } 87 | 88 | public void setUpdated(int updated) { 89 | this.updated = updated; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/IData.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | public interface IData { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/Message.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | /** 4 | * 5 | * @ClassName: Message 6 | * @Description: 消息类 7 | * @author ziye - ziye(at)mogujie.com 8 | * @date 2013-7-20 下午5:50:36 9 | * 10 | */ 11 | public class Message { 12 | 13 | // 消息id 14 | private int id; 15 | 16 | // 发送和接收的用户之间的关系Id,以relationship表中用户id小的在前的记录Id作为两个人的关系id 17 | private int relateId; 18 | 19 | private int fromUserId; 20 | 21 | private User fromUser; 22 | 23 | private int toUserId; 24 | 25 | private User toUser; 26 | 27 | private int type; 28 | 29 | private String content; 30 | 31 | private Audio audio; 32 | 33 | private int isDeleted; 34 | 35 | private int updated; 36 | 37 | private int created; 38 | 39 | public int getId() { 40 | return id; 41 | } 42 | 43 | public void setId(int id) { 44 | this.id = id; 45 | } 46 | 47 | public int getRelateId() { 48 | return relateId; 49 | } 50 | 51 | public void setRelateId(int relateId) { 52 | this.relateId = relateId; 53 | } 54 | 55 | public int getFromUserId() { 56 | return fromUserId; 57 | } 58 | 59 | public void setFromUserId(int fromUserId) { 60 | this.fromUserId = fromUserId; 61 | } 62 | 63 | public int getToUserId() { 64 | return toUserId; 65 | } 66 | 67 | public void setToUserId(int toUserId) { 68 | this.toUserId = toUserId; 69 | } 70 | 71 | public int getType() { 72 | return type; 73 | } 74 | 75 | public void setType(int type) { 76 | this.type = type; 77 | } 78 | 79 | public String getContent() { 80 | return content; 81 | } 82 | 83 | public void setContent(String content) { 84 | this.content = content; 85 | } 86 | 87 | public int getIsDeleted() { 88 | return isDeleted; 89 | } 90 | 91 | public void setIsDeleted(int isDeleted) { 92 | this.isDeleted = isDeleted; 93 | } 94 | 95 | public int getUpdated() { 96 | return updated; 97 | } 98 | 99 | public void setUpdated(int updated) { 100 | this.updated = updated; 101 | } 102 | 103 | public int getCreated() { 104 | return created; 105 | } 106 | 107 | public void setCreated(int created) { 108 | this.created = created; 109 | } 110 | 111 | public User getFromUser() { 112 | return fromUser; 113 | } 114 | 115 | public void setFromUser(User fromUser) { 116 | this.fromUser = fromUser; 117 | } 118 | 119 | public User getToUser() { 120 | return toUser; 121 | } 122 | 123 | public void setToUser(User toUser) { 124 | this.toUser = toUser; 125 | } 126 | 127 | public Audio getAudio() { 128 | return audio; 129 | } 130 | 131 | public void setAudio(Audio audio) { 132 | this.audio = audio; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/Relationship.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | /** 4 | * 5 | * @ClassName: Relationship 6 | * @Description: 好友关系 7 | * @author ziye - ziye(at)mogujie.com 8 | * @date 2013-7-20 下午5:50:10 9 | * 10 | */ 11 | public class Relationship { 12 | 13 | private int relateId; 14 | 15 | private int userId; 16 | 17 | private int friendUserId; 18 | 19 | private int status; 20 | 21 | private int created; 22 | 23 | private int updated; 24 | 25 | public int getRelateId() { 26 | return relateId; 27 | } 28 | 29 | public void setRelateId(int relateId) { 30 | this.relateId = relateId; 31 | } 32 | 33 | public int getUserId() { 34 | return userId; 35 | } 36 | 37 | public void setUserId(int userId) { 38 | this.userId = userId; 39 | } 40 | 41 | public int getFriendUserId() { 42 | return friendUserId; 43 | } 44 | 45 | public void setFriendUserId(int friendUserId) { 46 | this.friendUserId = friendUserId; 47 | } 48 | 49 | public int getStatus() { 50 | return status; 51 | } 52 | 53 | public void setStatus(int status) { 54 | this.status = status; 55 | } 56 | 57 | public int getCreated() { 58 | return created; 59 | } 60 | 61 | public void setCreated(int created) { 62 | this.created = created; 63 | } 64 | 65 | public int getUpdated() { 66 | return updated; 67 | } 68 | 69 | public void setUpdated(int updated) { 70 | this.updated = updated; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/TransmitFile.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | /** 4 | * 5 | * @Description: 群信息 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2014-1-5 下午4:17:55 8 | * 9 | */ 10 | public class TransmitFile { 11 | 12 | private int id; 13 | 14 | private int fromUserId; // 发送人 15 | 16 | private int toUserId; // 接收人 17 | 18 | private String taskId = ""; //任务编号 19 | 20 | private String filePath = ""; // 文件路径 21 | 22 | private int fileSize; //文件大小. 23 | 24 | private int status; // 状态,是否已经被接收 25 | 26 | private int created; // 创建时间 27 | 28 | private int updated; // 更新时间 29 | 30 | public int getId() { 31 | return id; 32 | } 33 | 34 | public void setId(int id) { 35 | this.id = id; 36 | } 37 | 38 | public int getFromUserId() { 39 | return fromUserId; 40 | } 41 | 42 | public void setFromUserId(int fromUserId) { 43 | this.fromUserId = fromUserId; 44 | } 45 | 46 | public int getToUserId() { 47 | return toUserId; 48 | } 49 | 50 | public void setToUserId(int toUserId) { 51 | this.toUserId = toUserId; 52 | } 53 | 54 | public String getFilePath() { 55 | return filePath; 56 | } 57 | 58 | public void setFilePath(String filePath) { 59 | this.filePath = filePath; 60 | } 61 | 62 | public int getCreated() { 63 | return created; 64 | } 65 | 66 | public void setCreated(int created) { 67 | this.created = created; 68 | } 69 | 70 | public int getUpdated() { 71 | return updated; 72 | } 73 | 74 | public void setUpdated(int updated) { 75 | this.updated = updated; 76 | } 77 | 78 | public int getStatus() { 79 | return status; 80 | } 81 | 82 | public void setStatus(int status) { 83 | this.status = status; 84 | } 85 | 86 | public int getFileSize() { 87 | return fileSize; 88 | } 89 | 90 | public void setFileSize(int fileSize) { 91 | this.fileSize = fileSize; 92 | } 93 | 94 | public String getTaskId() { 95 | return taskId; 96 | } 97 | 98 | public void setTaskId(String taskId) { 99 | this.taskId = taskId; 100 | } 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/data/User.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.data; 2 | 3 | /** 4 | * 5 | * @ClassName: User 6 | * @Description: 用户对象描述类 7 | * @author ziye - ziye(at)mogujie.com 8 | * @date 2013-7-20 下午5:49:23 9 | * 10 | */ 11 | public class User { 12 | 13 | protected int userId; // 用户id 14 | 15 | protected String uname; // 用户名 16 | 17 | protected String unick; // 用户昵称 18 | 19 | protected String avatar; // 用户头像 20 | 21 | protected String title; // 职务 22 | 23 | protected String position; // 地址,为什么不是address? 24 | 25 | protected int status; // 用户在职状态 0:正常(在职) 1:删除(离职) 可扩展 26 | 27 | protected int sex; // 性别 28 | 29 | protected int userType = 0; // 即identity,用户身份标识, 0-普通用户 1-管理员 30 | 31 | private int departId; // 部门id 32 | 33 | private int jobNumber; // 工号 34 | 35 | private String telphone; // 电话 36 | 37 | private String mail; // 邮箱 38 | 39 | private int created; // 创建时间 40 | 41 | private int updated; // 更新时间 42 | 43 | public int getUserId() { 44 | return userId; 45 | } 46 | 47 | public void setUserId(int userId) { 48 | this.userId = userId; 49 | } 50 | 51 | public String getUname() { 52 | return uname; 53 | } 54 | 55 | public void setUname(String uname) { 56 | this.uname = uname; 57 | } 58 | 59 | public String getAvatar() { 60 | return avatar; 61 | } 62 | 63 | public void setAvatar(String avatar) { 64 | this.avatar = avatar; 65 | } 66 | 67 | public int getDepartId() { 68 | return departId; 69 | } 70 | 71 | public void setDepartId(int departId) { 72 | this.departId = departId; 73 | } 74 | 75 | public String getUnick() { 76 | return unick; 77 | } 78 | 79 | public void setUnick(String unick) { 80 | this.unick = unick; 81 | } 82 | 83 | public String getTelphone() { 84 | return telphone; 85 | } 86 | 87 | public void setTelphone(String telphone) { 88 | this.telphone = telphone; 89 | } 90 | 91 | public int getCreated() { 92 | return created; 93 | } 94 | 95 | public void setCreated(int created) { 96 | this.created = created; 97 | } 98 | 99 | public int getUpdated() { 100 | return updated; 101 | } 102 | 103 | public void setUpdated(int updated) { 104 | this.updated = updated; 105 | } 106 | 107 | public int getSex() { 108 | return sex; 109 | } 110 | 111 | public void setSex(int sex) { 112 | this.sex = sex; 113 | } 114 | 115 | public String getTitle() { 116 | return title; 117 | } 118 | 119 | public void setTitle(String title) { 120 | this.title = title; 121 | } 122 | 123 | public String getPosition() { 124 | return position; 125 | } 126 | 127 | public void setPosition(String position) { 128 | this.position = position; 129 | } 130 | 131 | public int getStatus() { 132 | return status; 133 | } 134 | 135 | public void setStatus(int status) { 136 | this.status = status; 137 | } 138 | 139 | public int getUserType() { 140 | return userType; 141 | } 142 | 143 | public void setUserType(int user_type) { 144 | this.userType = user_type; 145 | } 146 | 147 | public int getJobNumber() { 148 | return jobNumber; 149 | } 150 | 151 | public void setJobNumber(int jobNumber) { 152 | this.jobNumber = jobNumber; 153 | } 154 | 155 | /** 156 | * @return the mail 157 | */ 158 | public String getMail() { 159 | return mail; 160 | } 161 | 162 | /** 163 | * @param mail 164 | * the mail to set 165 | */ 166 | public void setMail(String mail) { 167 | this.mail = mail; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/ActionContext.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.jboss.netty.channel.ChannelHandlerContext; 6 | 7 | import com.mogujie.ares.extend.filter.IFilter; 8 | import com.mogujie.ares.lib.net.DataBuffer; 9 | import com.mogujie.ares.lib.net.Packet; 10 | 11 | 12 | /** 13 | * 14 | * @Description: Action的描述类 15 | * @author ziye - ziye[at]mogujie.com 16 | * @date 2013-7-22 下午4:45:28 17 | * 18 | */ 19 | public class ActionContext { 20 | 21 | private BaseAction action; // Action对象Object 22 | 23 | private Method doMethod; // 处理业务的方法 24 | 25 | private RequestParams requestParams; // 请求参数控制器 26 | 27 | private int requestType; // 请求头的type 28 | 29 | private int defaultResponseType; // 默认响应的type 30 | 31 | private IFilter[] filters; // 过滤器们 32 | 33 | public BaseAction getAction() { 34 | return action; 35 | } 36 | 37 | public void setAction(BaseAction action) { 38 | this.action = action; 39 | } 40 | 41 | public Method getDoMethod() { 42 | return doMethod; 43 | } 44 | 45 | public void setDoMethod(Method doMethod) { 46 | this.doMethod = doMethod; 47 | } 48 | 49 | public RequestParams getRequestParams() { 50 | return requestParams; 51 | } 52 | 53 | public void setRequestParams(RequestParams requestParams) { 54 | this.requestParams = requestParams; 55 | } 56 | 57 | public int getRequestType() { 58 | return requestType; 59 | } 60 | 61 | public void setRequestType(int requestType) { 62 | this.requestType = requestType; 63 | } 64 | 65 | public int getDefaultResponseType() { 66 | return defaultResponseType; 67 | } 68 | 69 | public void setDefaultResponseType(int defaultResponseType) { 70 | this.defaultResponseType = defaultResponseType; 71 | } 72 | 73 | public IFilter[] getFilters() { 74 | return filters; 75 | } 76 | 77 | public void setFilters(IFilter[] filters) { 78 | this.filters = filters; 79 | } 80 | 81 | public Object invoke(ChannelHandlerContext context, Packet packet) throws Exception { 82 | // 解析请求的参数 83 | Object[] params = decode(packet.getContentBuffer(), context, this,packet.getVersion()); 84 | 85 | 86 | /* 87 | * 1.确定哪些处理器类是需要处理兼容版本的. 88 | * 2.需要兼容版本的多传一个请求过来的版本号. 89 | * 3.根据版本号.分别作相应的处理. 90 | 91 | 92 | if(action.isCompatibility()){ //需要考虑版本兼容性. 93 | Object[] newParams = new Object[params.length+1]; 94 | System.arraycopy(params, 0, newParams, 0, params.length); 95 | newParams[params.length]=packet.getVersion(); 96 | } 97 | */ 98 | 99 | return doMethod.invoke(action, params); // 调用 100 | } 101 | 102 | /** 103 | * 104 | * @Description: 数据包的解析,一个单纯的代理方法 105 | * @param dataBuffer 106 | * @param context 107 | * @return 108 | * @throws Exception 109 | */ 110 | public Object[] decode(DataBuffer dataBuffer, ChannelHandlerContext context, ActionContext actionContext,int version) throws Exception { 111 | return requestParams.decode(dataBuffer, context, actionContext,version); 112 | } 113 | 114 | // 发送消息 115 | public void sendResponse(ChannelHandlerContext context, Packet packet, DataBuffer responseBuffer) { 116 | Packet message = new Packet(); 117 | message.setVersion(packet.getVersion()); 118 | message.setServiceId(packet.getServiceId()); 119 | message.setCommandId(defaultResponseType); 120 | message.setReserved(packet.getReserved()); 121 | if(responseBuffer == null) { 122 | responseBuffer = new DataBuffer(0); 123 | } 124 | message.setContentBuffer(responseBuffer); 125 | 126 | context.getChannel().write(message); 127 | } 128 | } -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/ActionHolder.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.Map; 7 | import java.util.Map.Entry; 8 | 9 | import com.mogujie.ares.configure.Router; 10 | import com.mogujie.ares.configure.Router.ActionDescricptor; 11 | import com.mogujie.ares.extend.filter.IFilter; 12 | 13 | /** 14 | * 15 | * @Description: 16 | * action的集合,在系统初始化的时候会把所有的action都初始化一遍, 17 | * 缓存在这里,每个Action用一个ActionItem描述 18 | * ps: 这个类只在系统初始化的时候有修改,而且是单线程的, 19 | * 后面多线程的都是读操作,不用做并发控制 20 | * @author ziye - ziye[at]mogujie.com 21 | * @date 2013-7-22 下午4:22:55 22 | * 23 | */ 24 | public class ActionHolder { 25 | 26 | /** 27 | * key: 请求头上的type 28 | * value: 具体action的描述ActionItem 29 | */ 30 | private Map actionMap = new HashMap(); 31 | 32 | private Map actionObjectMap = new HashMap(); 33 | 34 | public ActionHolder() { 35 | } 36 | 37 | /** 38 | * 39 | * @Description: 根据请求的type获得相应的ActionItem 40 | * @param type 41 | * @return 42 | */ 43 | public ActionContext get(int type) { 44 | return actionMap.get(type); 45 | } 46 | 47 | /** 48 | * 49 | * @Description: 把一个Router里的所有的Action加入到Action中 50 | * @param router 51 | * @throws Exception 52 | */ 53 | public void put(Router router) throws Exception { 54 | if(router == null) { return ; } 55 | Map actionDescMap = router.getActionMap(); 56 | if(actionDescMap == null || actionDescMap.isEmpty()) { return ; } 57 | 58 | Iterator> it = actionDescMap.entrySet().iterator(); 59 | ActionDescricptor actionDesc = null; 60 | while(it.hasNext()) { 61 | Entry entry = it.next(); 62 | actionDesc = entry.getValue(); 63 | put(actionDesc); 64 | } 65 | } 66 | 67 | /** 68 | * 69 | * @Description: 新增一个Action 70 | * @param actionDesc 71 | * @throws Exception 72 | */ 73 | @SuppressWarnings({"rawtypes"}) 74 | public void put(ActionDescricptor actionDesc) throws Exception { 75 | 76 | if(actionDesc == null) { 77 | return ; 78 | } 79 | 80 | try { 81 | ActionContext item = new ActionContext(); 82 | 83 | // action类 84 | String className = actionDesc.getActionClass(); 85 | BaseAction actionObject = actionObjectMap.get(className); 86 | if(actionObject == null) { 87 | Class actionClazz = Class.forName(className); 88 | actionObject = (BaseAction)actionClazz.newInstance(); 89 | actionObjectMap.put(className, actionObject); 90 | } 91 | item.setAction(actionObject); 92 | 93 | // 请求参数 94 | RequestParams requestParams = new RequestParams(); 95 | Map paramsdefine = actionDesc.getParams(); 96 | Class[] paramTypes = requestParams.addParams(paramsdefine); 97 | item.setRequestParams(requestParams); 98 | 99 | // 处理业务逻辑的方法 100 | Method method = actionObject.getClass().getMethod(actionDesc.getMethod(), paramTypes); 101 | item.setDoMethod(method); 102 | 103 | // 请求类型 104 | item.setRequestType(actionDesc.getRequestType()); 105 | item.setDefaultResponseType(actionDesc.getResponseType()); 106 | 107 | // 过滤器,暂时还没有 108 | String[] strFilters = actionDesc.getFilters(); 109 | String fname; 110 | IFilter filter; 111 | Class filterClazz; 112 | IFilter[] filters = new IFilter[strFilters.length]; 113 | for(int i = 0; i < strFilters.length; i++) { 114 | fname = strFilters[i]; 115 | filterClazz = Class.forName(fname); 116 | filter = (IFilter)filterClazz.newInstance(); 117 | filters[i] = filter; 118 | } 119 | item.setFilters(filters); 120 | 121 | actionMap.put(item.getRequestType(), item); 122 | } catch (Exception e) { 123 | throw e; 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/BaseAction.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend; 2 | 3 | public abstract class BaseAction { 4 | } 5 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/action/Dashboard.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.action; 2 | 3 | import java.lang.management.ManagementFactory; 4 | 5 | import com.mogujie.ares.extend.BaseAction; 6 | import com.mogujie.ares.lib.net.DataBuffer; 7 | import com.sun.management.OperatingSystemMXBean; 8 | 9 | @SuppressWarnings("restriction") 10 | public class Dashboard extends BaseAction { 11 | 12 | private PerformanceMonitor cpuMonitor; 13 | 14 | public Dashboard() { 15 | // Create CPU monitoring class 16 | cpuMonitor = new PerformanceMonitor(); 17 | cpuMonitor.getCpuUsage(); // Set baseline 18 | } 19 | 20 | public DataBuffer getServerStatus(int version) { 21 | 22 | DataBuffer buffer = new DataBuffer(); 23 | 24 | // system info 25 | double cpu = roundToDecimals(cpuMonitor.getCpuUsage() * 100, 2); 26 | long freeMem = Runtime.getRuntime().freeMemory(); 27 | long maxMem = Runtime.getRuntime().maxMemory(); 28 | long totalMem = Runtime.getRuntime().totalMemory(); 29 | 30 | buffer.writeDouble(cpu); 31 | buffer.writeLong(freeMem); 32 | buffer.writeLong(maxMem); 33 | buffer.writeLong(totalMem); 34 | 35 | // threads list 36 | long totalThreadsCpuTime = 0; 37 | long[] threadIds = ManagementFactory.getThreadMXBean() 38 | .getAllThreadIds(); 39 | 40 | buffer.writeInt(threadIds.length); // 多少条线程. 41 | for (int i = 0; i < threadIds.length; i++) { 42 | long id = threadIds[i]; 43 | String name = ManagementFactory.getThreadMXBean().getThreadInfo(id) 44 | .getThreadName(); 45 | long cpuTime = 0; 46 | if (ManagementFactory.getThreadMXBean().isThreadCpuTimeSupported() 47 | && ManagementFactory.getThreadMXBean() 48 | .isThreadCpuTimeEnabled()) { 49 | cpuTime = ManagementFactory.getThreadMXBean().getThreadCpuTime( 50 | id); 51 | totalThreadsCpuTime += cpuTime; 52 | } 53 | buffer.writeLong(id); 54 | buffer.writeString(name); 55 | buffer.writeLong(cpuTime); 56 | } 57 | 58 | buffer.writeLong(totalThreadsCpuTime); 59 | 60 | return buffer; 61 | } 62 | 63 | private static double roundToDecimals(double d, int c) { 64 | int temp = (int) ((d * Math.pow(10, c))); 65 | return (double) (temp / Math.pow(10, c)); 66 | } 67 | 68 | private class PerformanceMonitor { 69 | private long lastSystemTime = 0; 70 | private long lastProcessCpuTime = 0; 71 | OperatingSystemMXBean osMxBean = (OperatingSystemMXBean) ManagementFactory 72 | .getOperatingSystemMXBean(); 73 | 74 | public synchronized double getCpuUsage() { 75 | if (lastSystemTime == 0) { 76 | baselineCounters(); 77 | return 0; 78 | } 79 | 80 | long systemTime = System.nanoTime(); 81 | long processCpuTime = osMxBean.getProcessCpuTime(); 82 | 83 | double cpuUsage = (double) (processCpuTime - lastProcessCpuTime) 84 | / (systemTime - lastSystemTime); 85 | 86 | lastSystemTime = systemTime; 87 | lastProcessCpuTime = processCpuTime; 88 | 89 | return cpuUsage / osMxBean.getAvailableProcessors(); 90 | } 91 | 92 | private void baselineCounters() { 93 | lastSystemTime = System.nanoTime(); 94 | lastProcessCpuTime = osMxBean.getProcessCpuTime(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/action/Login.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.action; 2 | 3 | import com.alibaba.druid.util.StringUtils; 4 | import com.mogujie.ares.data.User; 5 | import com.mogujie.ares.extend.BaseAction; 6 | import com.mogujie.ares.lib.logger.Logger; 7 | import com.mogujie.ares.lib.logger.LoggerFactory; 8 | import com.mogujie.ares.lib.net.DataBuffer; 9 | import com.mogujie.ares.model.LoginModel; 10 | import com.mogujie.ares.model.UserModel; 11 | import com.mogujie.ares.util.MoguUtil; 12 | 13 | /* 14 | * @Description: 用户登陆相关的请求 15 | * @author ziye - ziye[at]mogujie.com 16 | * @date 2013-7-21 下午1:28:17 17 | */ 18 | public class Login extends BaseAction { 19 | 20 | private static final Logger logger = LoggerFactory.getLogger(Login.class); 21 | 22 | /* 23 | * @Description: 用户登陆 24 | * 25 | * @param userId 用户Id 26 | * 27 | * @param token 登陆用户请求蘑菇街主站的http://www.mogujie.com/aresapi/login接口来获得 28 | * 29 | * @return 30 | */ 31 | public DataBuffer login(String uname, String pwd, DataBuffer attachment, 32 | int version) { 33 | logger.info("login: " + uname); 34 | int resultCode = 0; 35 | boolean isAuthed = false; 36 | User user = null; 37 | if (StringUtils.isEmpty(uname)) { 38 | resultCode = 1; 39 | } 40 | 41 | UserModel userModel = UserModel.getInstance(); 42 | try { 43 | isAuthed = LoginModel.getInstance().auth(uname, pwd); 44 | if (isAuthed) { 45 | user = userModel.getUserInfo(uname); 46 | } else { 47 | logger.info("login failed with error password!"); 48 | } 49 | } catch (Exception e) { 50 | logger.error("login failed with reason : ", e); 51 | isAuthed = false; 52 | } 53 | isAuthed = (isAuthed && (user != null)); // 用户要存在 54 | resultCode = (isAuthed ? 0 : 1); // 0: 成功,1: 失败 55 | DataBuffer buffer = new DataBuffer(); 56 | buffer.writeString(uname);// 用户名 57 | buffer.writeInt(resultCode); 58 | if (isAuthed) { 59 | buffer.writeInt(user.getUserId()); // 用户ID 60 | buffer.writeString(user.getUnick()); // 用户昵称 61 | buffer.writeString(user.getAvatar()); // 用户头像 62 | buffer.writeString(user.getTitle()); // 用户职称 63 | buffer.writeString(user.getPosition()); // 用户地址 64 | buffer.writeInt(user.getStatus()); // 用户在职等状态 65 | buffer.writeInt(user.getSex()); // 用户性别 66 | buffer.writeInt(user.getDepartId()); // 用户所在部门ID 67 | buffer.writeInt(user.getJobNumber()); // 用户工号 68 | buffer.writeString(user.getTelphone()); // 用户电话 69 | buffer.writeString(user.getMail()); // 用户邮箱 70 | logger.info("login success: " + uname + ", " + resultCode); 71 | } else { 72 | logger.info("login error: " + uname + ", " + resultCode); 73 | } 74 | 75 | return MoguUtil.writeAttachments(buffer, attachment); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/action/Monitor.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.action; 2 | 3 | import com.mogujie.ares.extend.BaseAction; 4 | import com.mogujie.ares.lib.logger.Logger; 5 | import com.mogujie.ares.lib.logger.LoggerFactory; 6 | import com.mogujie.ares.lib.net.DataBuffer; 7 | 8 | public class Monitor extends BaseAction { 9 | 10 | @SuppressWarnings("unused") 11 | private static final Logger logger = LoggerFactory.getLogger(Monitor.class); 12 | 13 | /** 14 | * 15 | * @Description: heartbeat 16 | * @param clientAddress 17 | * @return 18 | */ 19 | public DataBuffer heartbeat(String clientAddress, int version) { 20 | DataBuffer dataBuffer = new DataBuffer(0); 21 | return dataBuffer; // 不用返回 22 | } 23 | } -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/action/ServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.action; 2 | 3 | import com.mogujie.ares.extend.BaseAction; 4 | 5 | /** 6 | * 7 | * @Description: 处理服务端配置的请求. 8 | * @author zuoye - zuoye[at]mogujie.com 9 | * @date 2013-11-5 10 | * 11 | */ 12 | public class ServerConfig extends BaseAction { 13 | } 14 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/action/StatisticsContent.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.action; 2 | 3 | import java.sql.SQLException; 4 | 5 | import com.mogujie.ares.extend.BaseAction; 6 | import com.mogujie.ares.lib.logger.Logger; 7 | import com.mogujie.ares.lib.logger.LoggerFactory; 8 | import com.mogujie.ares.model.StatisticsModel; 9 | 10 | public class StatisticsContent extends BaseAction{ 11 | @SuppressWarnings("unused") 12 | private static final Logger logger = LoggerFactory.getLogger(StatisticsContent.class); 13 | 14 | //userId 15 | public void saveLog(int soure,int protocol,String ip,int userId,int actionType,String os,String userAgent,String flashVersion,String clientVersion,int version){ 16 | /* 17 | * C++ =>Java 18 | * source: web1. 19 | protocol: 2 20 | ip: 3707387924 21 | userId: 1000000 22 | os: Mac ox x 23 | userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36 24 | flash: 9.0.1 flashplayer 版本号 25 | client: 3.14 as或客户端息的版本号. 26 | */ 27 | 28 | /* logger.info("saveLog soure=" + soure 29 | + ", protocol=" + protocol + ", ip=" + ip 30 | + ", userId=" + userId+", actionType=" + actionType+ ", os=" + os+ ", userAgent=" + userAgent+ ", flashVersion=" + flashVersion+ ", clientVersion=" + clientVersion); 31 | */ 32 | try { 33 | StatisticsModel.getInstance().saveLog(soure, protocol, ip,actionType, userId, os, userAgent, flashVersion, clientVersion); 34 | } catch (SQLException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/dispatch/DefaultRequestDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.dispatch; 2 | 3 | import org.jboss.netty.channel.ChannelHandlerContext; 4 | import org.jboss.netty.channel.MessageEvent; 5 | 6 | import com.mogujie.ares.extend.ActionContext; 7 | import com.mogujie.ares.extend.ActionHolder; 8 | import com.mogujie.ares.lib.logger.Logger; 9 | import com.mogujie.ares.lib.logger.LoggerFactory; 10 | import com.mogujie.ares.lib.net.DataBuffer; 11 | import com.mogujie.ares.lib.net.IDispatcher; 12 | import com.mogujie.ares.lib.net.Packet; 13 | 14 | /** 15 | * 16 | * @Description: 默认的消息分发器,所有从BinaryMessageHandler传来的消息 17 | * 由这个类根据消息头的type分发到相应的Action 18 | * @author ziye - ziye[at]mogujie.com 19 | * @date 2013-7-21 上午11:21:34 20 | * 21 | */ 22 | public class DefaultRequestDispatcher implements IDispatcher { 23 | 24 | private static final Logger logger = LoggerFactory 25 | .getLogger(DefaultRequestDispatcher.class); 26 | 27 | private ActionHolder actionHolder; 28 | 29 | public DefaultRequestDispatcher(ActionHolder actionHolder) { 30 | this.actionHolder = actionHolder; 31 | } 32 | 33 | public ActionHolder getActionHolder() { 34 | return actionHolder; 35 | } 36 | 37 | public void setActionHolder(ActionHolder actionHolder) { 38 | this.actionHolder = actionHolder; 39 | } 40 | 41 | /** 42 | * 43 | * @Description: 消息分发函数,所有请求都由这个函数来分发 44 | * @param @param requestType 45 | * @param @return 46 | * @return ActionContext 47 | * @throws 48 | */ 49 | @Override 50 | public void dispatch(ChannelHandlerContext context, MessageEvent e) { 51 | 52 | Packet packet = (Packet) e.getMessage(); 53 | int type = packet.getCommandId(); 54 | 55 | ActionContext actionContext = actionHolder.get(type); // 取得请求对应的Action 56 | if (actionContext == null) { // 这里是有可能会返回null的 57 | logger.error("找不到指定的Action, type: " + type); 58 | return; 59 | } 60 | 61 | try { 62 | Object res = actionContext.invoke(context, packet); 63 | if (res != null) { 64 | actionContext.sendResponse(context, packet, (DataBuffer) res); // 发送结果 65 | } 66 | } catch (Exception e1) { // 如果出错了,临死前返回一个数据包给客户端... 67 | logger.error("commandId: " + packet.getCommandId(), e1); 68 | // actionContext.sendResponse(context, packet, new DataBuffer(0)); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/filter/IFilter.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.filter; 2 | 3 | /** 4 | * 5 | * @Description: 请求的过滤器 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2013-7-21 下午3:36:07 8 | * 9 | */ 10 | public interface IFilter { 11 | 12 | public void doFilter(); 13 | } 14 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/filter/LoginFilter.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.filter; 2 | 3 | /** 4 | * 5 | * @Description: 登陆请求的过滤处理 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2013-7-21 下午3:36:31 8 | * 9 | */ 10 | public class LoginFilter implements IFilter { 11 | 12 | @Override 13 | public void doFilter() { 14 | 15 | } 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/extend/filter/MessageContentFilter.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.extend.filter; 2 | 3 | /** 4 | * 5 | * @Description: 消息内容相关请求的过滤处理 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2013-7-21 下午3:36:51 8 | * 9 | */ 10 | public class MessageContentFilter implements IFilter { 11 | 12 | @Override 13 | public void doFilter() { 14 | // TODO Auto-generated method stub 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/logger/ConnectionKeepAliveFilter.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.logger; 2 | 3 | import ch.qos.logback.classic.spi.ILoggingEvent; 4 | import ch.qos.logback.core.filter.Filter; 5 | import ch.qos.logback.core.spi.FilterReply; 6 | 7 | /** 8 | * 9 | * @Description: heartbeat 之类和连接相关的日志过滤器 10 | * @author ziye - ziye[at]mogujie.com 11 | * @date 2013-7-21 下午3:37:45 12 | * 13 | */ 14 | public class ConnectionKeepAliveFilter extends Filter { 15 | 16 | @Override 17 | public FilterReply decide(ILoggingEvent event) { 18 | 19 | if (event.getMessage().contains("[LoggerFilter:Connection-Keep-alive]")) { 20 | return FilterReply.ACCEPT; 21 | } else { 22 | return FilterReply.DENY; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/logger/Logger.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.logger; 2 | // ziye copy from mdl-common 3 | public class Logger { 4 | 5 | private final org.slf4j.Logger logger; 6 | 7 | public Logger(Class key) { 8 | this.logger = org.slf4j.LoggerFactory.getLogger(key); 9 | } 10 | 11 | public Logger(String key) { 12 | this.logger = org.slf4j.LoggerFactory.getLogger(key); 13 | } 14 | 15 | private String appendContextMessage(String msg) { 16 | return "" + msg; 17 | } 18 | 19 | public void debug(String msg) { 20 | try { 21 | logger.debug(appendContextMessage(msg)); 22 | } catch (Throwable t) { 23 | } 24 | } 25 | 26 | public void debug(String msg, Throwable e) { 27 | try { 28 | logger.debug(appendContextMessage(msg), e); 29 | } catch (Throwable t) { 30 | } 31 | } 32 | 33 | public void info(String format, Object[] argArray){ 34 | try { 35 | logger.info(format,argArray); 36 | } catch (Throwable t) { 37 | } 38 | } 39 | 40 | public void info(String msg) { 41 | try { 42 | logger.info(appendContextMessage(msg)); 43 | } catch (Throwable t) { 44 | } 45 | } 46 | 47 | public void info(String msg, Throwable e) { 48 | try { 49 | logger.info(appendContextMessage(msg), e); 50 | } catch (Throwable t) { 51 | } 52 | } 53 | 54 | public void warn(String msg, Throwable e) { 55 | try { 56 | logger.warn(appendContextMessage(msg), e); 57 | } catch (Throwable t) { 58 | } 59 | } 60 | 61 | public void warn(String msg) { 62 | try { 63 | logger.warn(appendContextMessage(msg)); 64 | } catch (Throwable t) { 65 | } 66 | } 67 | 68 | public void error(String msg) { 69 | try { 70 | logger.error(appendContextMessage(msg)); 71 | } catch (Throwable t) { 72 | } 73 | } 74 | 75 | public void error(String msg, Throwable e) { 76 | try { 77 | logger.error(appendContextMessage(msg), e); 78 | } catch (Throwable t) { 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/logger/LoggerFactory.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.logger; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import java.util.concurrent.ConcurrentMap; 5 | // ziye copy from mdl-common 6 | public class LoggerFactory { 7 | 8 | private static final ConcurrentMap loggers = new ConcurrentHashMap(); 9 | 10 | public static Logger getLogger(Class key) { 11 | Logger logger = loggers.get(key.getName()); 12 | if (logger == null) { 13 | loggers.putIfAbsent(key.getName(), new Logger(key)); 14 | logger = loggers.get(key.getName()); 15 | } 16 | return logger; 17 | } 18 | 19 | public static Logger getLogger(String key) { 20 | Logger logger = loggers.get(key); 21 | if (logger == null) { 22 | loggers.putIfAbsent(key, new Logger(key)); 23 | logger = loggers.get(key); 24 | } 25 | return logger; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/logger/NoneFilteredLoggerFilter.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.logger; 2 | 3 | import ch.qos.logback.classic.spi.ILoggingEvent; 4 | import ch.qos.logback.core.filter.Filter; 5 | import ch.qos.logback.core.spi.FilterReply; 6 | 7 | /** 8 | * 9 | * @Description: 为过滤的一些通用日志的过滤器 10 | * @author ziye - ziye[at]mogujie.com 11 | * @date 2013-7-21 下午3:38:53 12 | * 13 | */ 14 | public class NoneFilteredLoggerFilter extends Filter { 15 | 16 | @Override 17 | public FilterReply decide(ILoggingEvent event) { 18 | 19 | if (event.getMessage().contains("[LoggerFilter:")) { 20 | return FilterReply.DENY; 21 | } else { 22 | return FilterReply.ACCEPT; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/net/BinaryMessageHandler.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.net; 2 | 3 | import org.jboss.netty.channel.ChannelHandlerContext; 4 | import org.jboss.netty.channel.ChannelStateEvent; 5 | import org.jboss.netty.channel.MessageEvent; 6 | import org.jboss.netty.channel.SimpleChannelHandler; 7 | 8 | import com.mogujie.ares.lib.logger.Logger; 9 | import com.mogujie.ares.lib.logger.LoggerFactory; 10 | import com.mogujie.ares.manager.NetworkManager; 11 | 12 | /** 13 | * 14 | * @Description: netty接收数据的handler,所有请求都在这里接收并转发到dispatcher 15 | * @author ziye - ziye[at]mogujie.com 16 | * @date 2013-7-21 下午3:39:34 17 | * 18 | */ 19 | public class BinaryMessageHandler extends SimpleChannelHandler { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(BinaryMessageHandler.class); 22 | 23 | private IDispatcher dispatcher; 24 | 25 | public BinaryMessageHandler(IDispatcher dispatcher) { 26 | this.dispatcher = dispatcher; 27 | } 28 | 29 | /** 30 | * 客户端建立连接 31 | * (non-Javadoc) 32 | * @see org.jboss.netty.channel.SimpleChannelHandler#channelConnected(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ChannelStateEvent) 33 | */ 34 | public void channelConnected(ChannelHandlerContext context, ChannelStateEvent e) 35 | throws Exception { 36 | String clientAddr = context.getChannel().getRemoteAddress().toString(); 37 | logger.info("[LoggerFilter:Connection-Keep-alive] client " + clientAddr + " Connected"); 38 | NetworkManager.getInstance().addClient(context); // 添加到现有客户端的列表里 39 | super.channelConnected(context, e); 40 | } 41 | 42 | /** 43 | * 收到数据的事件 44 | */ 45 | @Override 46 | public void messageReceived(ChannelHandlerContext context, MessageEvent e) 47 | throws Exception { 48 | try{ 49 | dispatcher.dispatch(context, e); 50 | } catch(Exception exception) { 51 | logger.error("dispatch error. ", exception); 52 | } 53 | } 54 | 55 | /** 56 | * 客户端断开连接 57 | * (non-Javadoc) 58 | * @see org.jboss.netty.channel.SimpleChannelHandler#channelDisconnected(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ChannelStateEvent) 59 | */ 60 | public void channelDisconnected(ChannelHandlerContext context, 61 | ChannelStateEvent e) throws Exception { 62 | String clientAddr = context.getChannel().getRemoteAddress().toString(); 63 | logger.info("[LoggerFilter:Connection-Keep-alive] client " + clientAddr + " Disconnected"); 64 | NetworkManager.getInstance().removeClient(context); // 从现有客户端列表里移除该连接 65 | super.channelDisconnected(context, e); 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/net/FrameBinaryDecoder.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.net; 2 | 3 | import org.jboss.netty.buffer.ChannelBuffer; 4 | import org.jboss.netty.buffer.ChannelBuffers; 5 | import org.jboss.netty.channel.Channel; 6 | import org.jboss.netty.channel.ChannelHandlerContext; 7 | import org.jboss.netty.handler.codec.frame.FrameDecoder; 8 | 9 | import com.mogujie.ares.configure.SysConstants; 10 | import com.mogujie.ares.lib.logger.Logger; 11 | import com.mogujie.ares.lib.logger.LoggerFactory; 12 | 13 | /** 14 | * 15 | * @Description: 数据包解析器 16 | * @author ziye - ziye[at]mogujie.com 17 | * @date 2013-7-21 下午3:44:58 18 | * 19 | */ 20 | public class FrameBinaryDecoder extends FrameDecoder { 21 | 22 | private static final Logger logger = LoggerFactory 23 | .getLogger(FrameBinaryDecoder.class); 24 | 25 | /** 26 | * 解析数据包,主要负责解析数据包前8个字节统一格式的头部信息,生成Packet对象, 剩余的数据部分的解析在后面具体的action处理 27 | */ 28 | @Override 29 | protected Object decode(ChannelHandlerContext ctx, Channel channel, 30 | ChannelBuffer buffer) throws Exception { 31 | 32 | if (buffer.readableBytes() < SysConstants.PROTOCOL_HEADER_LENGTH) { 33 | return null; 34 | } 35 | 36 | buffer.markReaderIndex(); // 标记一下 37 | int length = buffer.readInt(); // 消息长度 38 | char serviceId = buffer.readChar(); // 服务号, 后端这边固定1000 39 | char commandId = buffer.readChar(); // 命令号 40 | char version = buffer.readChar(); // 消息version, 1个字节 41 | char reserved = buffer.readChar(); // 保留,可用户如序列号等 42 | int contentLength = length - SysConstants.PROTOCOL_HEADER_LENGTH; // 计算数据包中业务数据部分的长度(去除头部长度16) 43 | 44 | if (buffer.readableBytes() < contentLength) { 45 | logger.info("数据长度:" + contentLength); 46 | buffer.resetReaderIndex(); // 返回到上面标记的位置 47 | return null; 48 | } 49 | 50 | ChannelBuffer cBuffer = ChannelBuffers.buffer(contentLength); 51 | buffer.readBytes(cBuffer, contentLength); // 转移所有业务部分的数据到新的byte 52 | 53 | Packet packet = new Packet(); 54 | packet.setLength(contentLength); 55 | packet.setServiceId(serviceId); 56 | packet.setCommandId(commandId); 57 | packet.setVersion(version); 58 | packet.setReserved(reserved); 59 | DataBuffer dataBuffer = new DataBuffer(cBuffer); // 数据部分 60 | packet.setContentBuffer(dataBuffer); 61 | 62 | // logger.info("decode packet serviceId : " + packet.getServiceId() 63 | // + " commandId: " + packet.getCommandId()); 64 | return packet; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/net/FrameBinaryEncoder.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.net; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import org.jboss.netty.buffer.ChannelBuffer; 6 | import org.jboss.netty.buffer.ChannelBuffers; 7 | import org.jboss.netty.channel.ChannelHandlerContext; 8 | import org.jboss.netty.channel.Channels; 9 | import org.jboss.netty.channel.MessageEvent; 10 | import org.jboss.netty.channel.SimpleChannelDownstreamHandler; 11 | 12 | import com.mogujie.ares.configure.SysConstants; 13 | import com.mogujie.ares.lib.logger.Logger; 14 | import com.mogujie.ares.lib.logger.LoggerFactory; 15 | 16 | /** 17 | * 18 | * @Description: 数据编码器,把要发送的数据按照一定格式拼接成二进制的流 19 | * @author ziye - ziye[at]mogujie.com 20 | * @date 2013-7-21 下午4:02:07 21 | * 22 | */ 23 | public class FrameBinaryEncoder extends SimpleChannelDownstreamHandler { 24 | @SuppressWarnings("unused") 25 | private static final Logger logger = LoggerFactory 26 | .getLogger(FrameBinaryEncoder.class); 27 | 28 | /** 29 | * @Description: 把要发送的数据编码成二进制数据并发送 30 | */ 31 | public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) 32 | throws Exception { 33 | 34 | Packet request = (Packet) e.getMessage(); 35 | // encode 36 | DataBuffer contentBuffer = request.getContentBuffer(); 37 | ChannelBuffer dataBuffer = null; 38 | if (contentBuffer != null) { 39 | dataBuffer = contentBuffer.getOrignalBuffer(); 40 | } // 数据部分 41 | ChannelBuffer totalBuffer; 42 | ByteBuffer headBuffer = ByteBuffer 43 | .allocate(SysConstants.PROTOCOL_HEADER_LENGTH); 44 | if (dataBuffer != null) { 45 | int length = dataBuffer.readableBytes() 46 | + SysConstants.PROTOCOL_HEADER_LENGTH; // 总的包长 47 | headBuffer.putInt(length);// 消息长度 48 | char[] tc = Character.toChars(request.getServiceId()); 49 | headBuffer.putChar(tc[0]); // 服务号, 后端这边固定1000 50 | tc = Character.toChars(request.getCommandId()); 51 | headBuffer.putChar(tc[0]); // 命令号 52 | tc = Character.toChars(request.getVersion()); 53 | headBuffer.putChar(tc[0]);// 消息version, 1个字节 54 | tc = Character.toChars(request.getReserved()); 55 | headBuffer.putChar(tc[0]); // 保留,可用于序列号等 56 | headBuffer.flip(); // 这里需要重置一下游标和长度 57 | 58 | totalBuffer = ChannelBuffers.dynamicBuffer(); 59 | totalBuffer.writeBytes(headBuffer); 60 | if (length > SysConstants.PROTOCOL_HEADER_LENGTH) { // 数据部分长度不为0才写入 61 | int dataLength = dataBuffer.readableBytes(); 62 | byte[] data = new byte[dataLength]; 63 | dataBuffer.readBytes(data); 64 | totalBuffer.writeBytes(data); 65 | } 66 | } else { 67 | int length = SysConstants.PROTOCOL_HEADER_LENGTH; // 总的包长 68 | headBuffer.putInt(length);// 消息长度 69 | char[] tc = Character.toChars(request.getServiceId()); 70 | headBuffer.putChar(tc[0]); // 服务号, 后端这边固定1000 71 | tc = Character.toChars(request.getCommandId()); 72 | headBuffer.putChar(tc[0]); // 命令号 TODO 73 | headBuffer.put((byte) request.getVersion());// 消息version, 1个字节 74 | tc = Character.toChars(request.getReserved()); 75 | headBuffer.putChar(tc[0]); // 保留,可用户如序列号等 76 | headBuffer.flip(); // 这里需要重置一下游标和长度 77 | 78 | totalBuffer = ChannelBuffers.copiedBuffer(headBuffer); 79 | } 80 | // logger.info("encode serviceId : " + request.getServiceId() 81 | // + " commandId: " + request.getCommandId()); 82 | Channels.write(ctx, e.getFuture(), totalBuffer); 83 | //logger.info("发送totalBuffer : " + totalBuffer.toString(Charset.defaultCharset())); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/net/IDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.net; 2 | 3 | import org.jboss.netty.channel.ChannelHandlerContext; 4 | import org.jboss.netty.channel.MessageEvent; 5 | 6 | /** 7 | * 8 | * @ClassName: IDispatcher 9 | * @Description: 请求分发的接口 10 | * @author ziye - ziye(at)mogujie.com 11 | * @date 2013-7-20 下午5:55:47 12 | * 13 | */ 14 | public interface IDispatcher { 15 | 16 | public void dispatch(ChannelHandlerContext context, MessageEvent e); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/net/IMHttpResponse.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.net; 2 | 3 | /** 4 | * 5 | * @Description: http返回值 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2014-3-9 下午10:21:08 8 | * 9 | */ 10 | public class IMHttpResponse { 11 | private int statusCode; 12 | private String responseBody; 13 | 14 | public int getStatusCode() { 15 | return statusCode; 16 | } 17 | 18 | public void setStatusCode(int statusCode) { 19 | this.statusCode = statusCode; 20 | } 21 | 22 | public String getResponseBody() { 23 | return responseBody; 24 | } 25 | 26 | public void setResponseBody(String responseBody) { 27 | this.responseBody = responseBody; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "IMHttpResponse [statusCode=" + statusCode + ", responseBody=" 33 | + responseBody + "]"; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/net/MoguHttpResponse.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.net; 2 | 3 | /** 4 | * 5 | * @Description: http返回值 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2014-3-9 下午10:21:08 8 | * 9 | */ 10 | public class MoguHttpResponse { 11 | private int statusCode; 12 | private String responseBody; 13 | 14 | public int getStatusCode() { 15 | return statusCode; 16 | } 17 | 18 | public void setStatusCode(int statusCode) { 19 | this.statusCode = statusCode; 20 | } 21 | 22 | public String getResponseBody() { 23 | return responseBody; 24 | } 25 | 26 | public void setResponseBody(String responseBody) { 27 | this.responseBody = responseBody; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "IMHttpResponse [statusCode=" + statusCode + ", responseBody=" 33 | + responseBody + "]"; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/net/Packet.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.net; 2 | 3 | /** 4 | * 5 | * @Description: 发送和接收的数据包 6 | * @author ziye - ziye[at]mogujie.com 7 | * @date 2013-7-21 下午4:14:31 8 | * 9 | */ 10 | public class Packet { 11 | 12 | private int length; // 数据包长度,包括包头 13 | 14 | private int version; // 版本号 15 | 16 | private int serviceId; // 服务号, 后端这边固定1000 17 | 18 | private int commandId; // 命令号, 标识服务接口, 19 | 20 | private int reserved; // 保留,可用于如序列号等 21 | 22 | private DataBuffer contentBuffer; // 业务数据部分 23 | 24 | public int getLength() { 25 | return length; 26 | } 27 | 28 | public void setLength(int length) { 29 | this.length = length; 30 | } 31 | 32 | public int getVersion() { 33 | return version; 34 | } 35 | 36 | public void setVersion(int version) { 37 | this.version = version; 38 | } 39 | 40 | public int getServiceId() { 41 | return serviceId; 42 | } 43 | 44 | public void setServiceId(int serviceId) { 45 | this.serviceId = serviceId; 46 | } 47 | 48 | public int getCommandId() { 49 | return commandId; 50 | } 51 | 52 | public void setCommandId(int commandId) { 53 | this.commandId = commandId; 54 | } 55 | 56 | public int getReserved() { 57 | return reserved; 58 | } 59 | 60 | public void setReserved(int reserved) { 61 | this.reserved = reserved; 62 | } 63 | 64 | public DataBuffer getContentBuffer() { 65 | return contentBuffer; 66 | } 67 | 68 | public void setContentBuffer(DataBuffer contentBuffer) { 69 | this.contentBuffer = contentBuffer; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/lib/storage/CachePool.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.lib.storage; 2 | 3 | import com.mogujie.ares.configure.SysConstants; 4 | 5 | import redis.clients.jedis.Jedis; 6 | import redis.clients.jedis.JedisPool; 7 | import redis.clients.jedis.JedisPoolConfig; 8 | 9 | /** 10 | * 11 | * @Description: 缓存的连接池 12 | * @author shitou - shitou[at]mogujie.com 13 | * @date 2013-7-21 下午4:15:34 14 | * 15 | */ 16 | public class CachePool { 17 | 18 | private JedisPool pool = null; 19 | 20 | private JedisPoolConfig poolConfig = null; 21 | 22 | private String host; // 缓存的服务器 23 | private int port; // 端口 24 | private int db; // 连接到第几个db 25 | 26 | public CachePool(String host, Integer port, Integer db) 27 | { 28 | this.host = host; 29 | this.port = port; 30 | this.db = db; 31 | } 32 | 33 | /** 34 | * @Description: 初始化配置 35 | */ 36 | public void initialConfig() 37 | { 38 | if(poolConfig == null) 39 | { 40 | poolConfig = new JedisPoolConfig(); 41 | poolConfig.setTestOnBorrow(SysConstants.TEST_ON_BORROW); // 从数据库连接池中取得连接时,对其的有效性进行检查 42 | poolConfig.setMaxActive(SysConstants.MAX_ACTIVE); // 最大连接数 43 | poolConfig.setMaxIdle(SysConstants.MAX_IDLE); // 最大闲置的连接数 44 | poolConfig.setMinIdle(SysConstants.MIN_IDLE); // 最少 45 | poolConfig.setMaxWait(SysConstants.MAX_WAIT); // 请求最长等待时间/毫秒 46 | poolConfig.setTestWhileIdle(SysConstants.TEST_WHILE_IDLE); // 闲置时测试 47 | } 48 | } 49 | 50 | /** 51 | * 52 | * @Description: 初始化 53 | */ 54 | public void launch() 55 | { 56 | if(pool == null) 57 | { 58 | initialConfig(); 59 | pool = new JedisPool(poolConfig, this.host, this.port); 60 | } 61 | } 62 | 63 | /** 64 | * 65 | * @Description: 销毁 66 | */ 67 | public void destory() 68 | { 69 | if(pool != null) 70 | { 71 | pool.destroy(); 72 | } 73 | } 74 | 75 | /** 76 | * 77 | * @Description: 获得连接 78 | * @return redis的连接 79 | */ 80 | public Jedis getResource() 81 | { 82 | Jedis jedisInstance = null; 83 | if(pool != null) 84 | { 85 | jedisInstance = pool.getResource(); 86 | if(db > 0) 87 | { 88 | jedisInstance.select(db); 89 | } 90 | } 91 | return jedisInstance; 92 | } 93 | 94 | /** 95 | * 96 | * @Description: 释放连接 97 | * @param jedisInstance 98 | */ 99 | public void returnResource(Jedis jedisInstance) 100 | { 101 | pool.returnResource(jedisInstance); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/manager/ConfigureManager.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.manager; 2 | 3 | import java.util.HashMap; 4 | import java.util.Properties; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | import com.mogujie.ares.configure.Configure; 8 | import com.mogujie.ares.configure.Router; 9 | import com.mogujie.ares.lib.logger.Logger; 10 | import com.mogujie.ares.lib.logger.LoggerFactory; 11 | /** 12 | * 13 | * @Description: 配置管理类, 单例 14 | * @author shitou - shitou[at]mogujie.com 15 | * @date 2013-7-22 上午11:15:23 16 | * 17 | */ 18 | public class ConfigureManager 19 | { 20 | 21 | public static final Logger logger = LoggerFactory.getLogger(ConfigureManager.class); 22 | 23 | private static ConfigureManager _configureManagerInstance = null; 24 | 25 | public static ConfigureManager getInstance() 26 | { 27 | if(_configureManagerInstance == null) 28 | { 29 | _configureManagerInstance = new ConfigureManager(); 30 | } 31 | return _configureManagerInstance; 32 | } 33 | 34 | private Configure configure; 35 | 36 | private ConfigureManager() 37 | { 38 | configure = new Configure(); 39 | } 40 | 41 | /** 42 | * 初始化配置,只在启动时调用 43 | */ 44 | public void initial() throws Exception 45 | { 46 | reloadAllConfigs(); 47 | } 48 | 49 | /** 50 | * db的配置 51 | * @return 52 | */ 53 | public Properties getDBConfig() 54 | { 55 | return configure.getDBConfig(); 56 | } 57 | 58 | /** 59 | * cache(redis)配置 60 | * @return 61 | */ 62 | public Properties getCacheConfig() 63 | { 64 | return configure.getCacheConfig(); 65 | } 66 | 67 | /** 68 | * 阿瑞斯系统配置 69 | * @return 70 | */ 71 | public Properties getSystemConfig() 72 | { 73 | return configure.getSystemConfig(); 74 | } 75 | 76 | public Router getActionRouter() { 77 | return configure.getActionRouter(); 78 | } 79 | 80 | /** 81 | * 计划任务脚本配置 82 | * @return 83 | */ 84 | public ConcurrentHashMap> getTimerConfig() 85 | { 86 | return configure.getTimerConfig(); 87 | } 88 | 89 | /** 90 | * 装载数据 91 | * @throws Exception 92 | */ 93 | public void loadAllConfigs() throws Exception 94 | { 95 | configure.loadConfigs(); 96 | } 97 | 98 | /** 99 | * 重新装载数据 100 | * @throws Exception 101 | */ 102 | public void reloadAllConfigs() throws Exception { 103 | loadAllConfigs(); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/manager/FileManager.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.manager; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | 5 | import com.mogujie.ares.lib.logger.Logger; 6 | import com.mogujie.ares.lib.logger.LoggerFactory; 7 | import com.mogujie.ares.lib.net.MoguHttp; 8 | 9 | public class FileManager { 10 | 11 | public static String fileServerUrl = ""; 12 | 13 | private static final Logger logger = LoggerFactory.getLogger(FileManager.class); 14 | private static FileManager instance = new FileManager(); 15 | 16 | public static FileManager getInstance() 17 | { 18 | if(instance == null) 19 | { 20 | instance = new FileManager(); 21 | } 22 | return instance; 23 | } 24 | 25 | /** 26 | * 27 | * @Description: 返回音频文件 28 | * @param bytes 29 | * @param userId 30 | * @return 31 | */ 32 | public String saveAudioBinary(byte[] bytes) { 33 | 34 | if(bytes == null || bytes.length == 0) { 35 | return ""; 36 | } 37 | 38 | String fileName = MoguHttp.uploadAudioByteFile(FileManager.fileServerUrl, bytes); 39 | if(StringUtils.isEmpty(fileName)) { 40 | logger.info("保存语音文件失败"); 41 | } else { 42 | logger.info("保存语音文件成功:" + fileName); 43 | } 44 | return fileName; 45 | } 46 | 47 | /** 48 | * 49 | * @Description: 从磁盘读取一个文件 50 | * @param fileName 51 | * @return 52 | */ 53 | public byte[] readAudioBinary(String fileName) { 54 | if(StringUtils.isEmpty(fileName)) { 55 | return null; 56 | } 57 | String strDownloadUrl = FileManager.fileServerUrl + fileName; 58 | logger.info("下载文件:" + strDownloadUrl); 59 | byte[] bytes = MoguHttp.downloadByteFile(strDownloadUrl); 60 | 61 | return bytes; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/model/DepartModel.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.model; 2 | 3 | import java.sql.Connection; 4 | import java.sql.PreparedStatement; 5 | import java.sql.ResultSet; 6 | import java.sql.SQLException; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | import com.mogujie.ares.data.Department; 11 | import com.mogujie.ares.lib.logger.Logger; 12 | import com.mogujie.ares.lib.logger.LoggerFactory; 13 | import com.mogujie.ares.manager.DBManager; 14 | import com.mogujie.ares.manager.DBManager.DBPoolName; 15 | 16 | /* 17 | * @Description: 部门相关的model 18 | * @author ziye 19 | * 20 | */ 21 | public class DepartModel { 22 | 23 | private static DepartModel instance = new DepartModel(); 24 | @SuppressWarnings("unused") 25 | private final Logger logger = LoggerFactory.getLogger(DepartModel.class); 26 | 27 | public static DepartModel getInstance() { 28 | if (instance == null) { 29 | instance = new DepartModel(); 30 | } 31 | return instance; 32 | } 33 | 34 | /* 35 | * @Description: 获取所有部门信息 36 | * 37 | * @return Map 部门的具体信息Map 38 | * 39 | * @throws SQLException 40 | */ 41 | public Map getDepartmentInfo() throws SQLException { 42 | Map departInfos = new HashMap(); 43 | DBManager dbManager = DBManager.getInstance(); 44 | Connection conn = dbManager.getConnection(DBPoolName.macim_slave); 45 | PreparedStatement statement = null; 46 | ResultSet rs = null; 47 | try { 48 | String sql = "select * from IMDepartment where status = 0"; 49 | statement = conn.prepareStatement(sql); 50 | rs = statement.executeQuery(); 51 | Department department = null; 52 | int departId = 0; 53 | while (rs.next()) { 54 | department = new Department(); 55 | departId = rs.getInt("id"); 56 | department.setDepartId(departId); 57 | department.setTitle(rs.getString("title")); 58 | department.setLeader(rs.getInt("leader")); 59 | department.setParentDepartId(rs.getInt("pid")); 60 | department.setStatus(rs.getInt("status")); 61 | department.setDescription(rs.getString("desc")); 62 | departInfos.put(departId, department); 63 | } 64 | } catch (SQLException e) { 65 | throw e; 66 | } finally { 67 | dbManager.release(DBPoolName.macim_slave, conn, statement, rs); 68 | } 69 | 70 | return departInfos; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/model/LoginModel.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.model; 2 | 3 | import java.sql.Connection; 4 | import java.sql.PreparedStatement; 5 | import java.sql.ResultSet; 6 | import java.sql.SQLException; 7 | 8 | import com.alibaba.druid.util.StringUtils; 9 | import com.mogujie.ares.lib.logger.Logger; 10 | import com.mogujie.ares.lib.logger.LoggerFactory; 11 | import com.mogujie.ares.manager.DBManager; 12 | import com.mogujie.ares.manager.DBManager.DBPoolName; 13 | import com.mogujie.ares.util.MoguUtil; 14 | 15 | /* 16 | * @Description: 登陆相关的所有操作 17 | * @author shuchen - shuchen[at]mogujie.com 18 | * @date 2014-08-04 下午3:20:01 19 | */ 20 | public class LoginModel { 21 | private static LoginModel instance = new LoginModel(); 22 | private static final Logger logger = LoggerFactory 23 | .getLogger(LoginModel.class); 24 | 25 | public static LoginModel getInstance() { 26 | if (instance == null) { 27 | instance = new LoginModel(); 28 | } 29 | return instance; 30 | } 31 | 32 | private LoginModel() { 33 | 34 | } 35 | 36 | /* 37 | * 38 | * @Description: 登陆的验证接口,直接DB拉取已加密密码验证 39 | * 40 | * @param mogujieSession 41 | * 42 | * @return 43 | * 44 | * @throws Exception 45 | */ 46 | public boolean auth(String uname, String pwd) throws Exception { 47 | boolean isAuthed = false; // model层不做参数为空判断,会在action层做掉 48 | DBManager dbManager = DBManager.getInstance(); 49 | Connection conn = dbManager.getConnection(DBPoolName.macim_slave); 50 | PreparedStatement statement = null; 51 | ResultSet rs = null; 52 | try { 53 | String sql = "select pwd, status from IMUsers where uname = " 54 | + MoguUtil.getArgsHolder(1); 55 | statement = conn.prepareStatement(sql); 56 | statement.setString(1, uname); 57 | rs = statement.executeQuery(); 58 | String passwd = ""; 59 | int status = 0; 60 | while (rs.next()) { 61 | passwd = rs.getString("pwd"); 62 | status = rs.getInt("status"); 63 | logger.info("login: " + uname); 64 | if (status == 0 && !StringUtils.isEmpty(passwd) && passwd.equals(pwd)) { 65 | isAuthed = true; 66 | } 67 | } 68 | } catch (SQLException e) { 69 | throw e; 70 | } finally { 71 | dbManager.release(DBPoolName.macim_slave, conn, statement, rs); 72 | } 73 | return isAuthed; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/model/ServerConfigModel.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.model; 2 | 3 | /* 4 | * 5 | * @Description: 服务配置相关操作 6 | * @author zuoye - zuoye[at]mogujie.com 7 | * @date 2013-11-5 8 | * 9 | */ 10 | public class ServerConfigModel { 11 | 12 | private static ServerConfigModel configModelInstance; 13 | 14 | public static ServerConfigModel getInstance() { 15 | if (configModelInstance == null) { 16 | configModelInstance = new ServerConfigModel(); 17 | } 18 | return configModelInstance; 19 | } 20 | 21 | private ServerConfigModel() { 22 | } 23 | 24 | public String getSensitivityWord() throws Exception { 25 | return ""; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/model/StatisticsModel.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.model; 2 | 3 | import java.net.InetAddress; 4 | import java.net.UnknownHostException; 5 | import java.sql.Connection; 6 | import java.sql.PreparedStatement; 7 | import java.sql.SQLException; 8 | 9 | import com.mogujie.ares.manager.DBManager; 10 | import com.mogujie.ares.manager.DBManager.DBPoolName; 11 | 12 | /* 13 | * @Description: 统计模块处理. 14 | * @author zuoye@mogujie.com 15 | */ 16 | public class StatisticsModel { 17 | private static StatisticsModel instance = new StatisticsModel(); 18 | 19 | public static StatisticsModel getInstance() { 20 | if (instance == null) { 21 | instance = new StatisticsModel(); 22 | } 23 | return instance; 24 | } 25 | 26 | public void saveLog(int soure, int protocol, String ip, int type, 27 | int userId, String os, String userAgent, String flashVersion, 28 | String clientVersion) throws SQLException { 29 | DBManager dbManager = DBManager.getInstance(); 30 | Connection conn = dbManager.getConnection(DBPoolName.macim_master); 31 | PreparedStatement statement = null; 32 | try { 33 | String sql = " insert into IMLogging (source,protocol,ip,type,userId,os,userAgent,flash,client,created) values(?,?,?,?,?,?,?,?,?,?)"; 34 | statement = conn.prepareStatement(sql); 35 | int index = 1; 36 | statement.setObject(index++, soure); 37 | statement.setObject(index++, protocol); 38 | statement.setObject(index++, ip2long(ip)); 39 | statement.setObject(index++, type); 40 | statement.setObject(index++, userId); 41 | statement.setObject(index++, os); 42 | statement.setObject(index++, userAgent); 43 | statement.setObject(index++, flashVersion); 44 | statement.setObject(index++, clientVersion); 45 | statement.setObject(index++, System.currentTimeMillis() / 1000); 46 | statement.executeUpdate(); 47 | } catch (SQLException e) { 48 | throw e; 49 | } finally { 50 | dbManager.release(DBPoolName.macim_master, conn, statement, null); 51 | } 52 | } 53 | 54 | public long ip2long(String ip) { 55 | int ipNum = 0; 56 | try { 57 | ipNum = str2Ip(ip); 58 | } catch (UnknownHostException e) { 59 | e.printStackTrace(); 60 | } 61 | return int2long(ipNum); 62 | } 63 | 64 | public long int2long(int i) { 65 | long l = i & 0x7fffffffL; 66 | if (i < 0) { 67 | l |= 0x080000000L; 68 | } 69 | return l; 70 | } 71 | 72 | public int str2Ip(String ip) throws UnknownHostException { 73 | InetAddress address = InetAddress.getByName(ip);// 在给定主机名的情况下确定主机的 IP 址。 74 | byte[] bytes = address.getAddress();// 返回此 InetAddress 对象的原始 IP 地址 75 | int a, b, c, d; 76 | a = byte2int(bytes[0]); 77 | b = byte2int(bytes[1]); 78 | c = byte2int(bytes[2]); 79 | d = byte2int(bytes[3]); 80 | int result = (a << 24) | (b << 16) | (c << 8) | d; 81 | return result; 82 | } 83 | 84 | public int byte2int(byte b) { 85 | int l = b & 0x07f; 86 | if (b < 0) { 87 | l |= 0x80; 88 | } 89 | return l; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/timer/ConfigureReloadTask.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.timer; 2 | 3 | import com.mogujie.ares.lib.logger.Logger; 4 | import com.mogujie.ares.lib.logger.LoggerFactory; 5 | 6 | /** 7 | * 8 | * @Description: 配置实时更新的类 9 | * @author shitou - shitou[at]mogujie.com 10 | * @date 2013-7-22 下午2:54:08 11 | * 12 | */ 13 | public class ConfigureReloadTask implements Runnable 14 | { 15 | private Logger logger = LoggerFactory.getLogger(ConfigureReloadTask.class); 16 | @Override 17 | public void run() 18 | { 19 | //重载所有的配置 20 | //ConfigureManager.getInstance().reloadAllConfigs(); 21 | logger.info("Hello World"); 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/timer/Timer.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.timer; 2 | 3 | import java.util.Properties; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.ScheduledExecutorService; 6 | import java.util.concurrent.ScheduledFuture; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import com.mogujie.ares.manager.ConfigureManager; 10 | 11 | /** 12 | * 13 | * @Description: 定时器,实际上就是一个ScheduledExecutorService的封装类 14 | * @author shitou - shitou[at]mogujie.com 15 | * @date 2013-7-22 下午2:55:21 16 | * 17 | */ 18 | public class Timer 19 | { 20 | private Properties systemProperties; 21 | 22 | private ScheduledExecutorService schedulerService; // 线程池 23 | 24 | private boolean isLaunch = false; 25 | 26 | private static Timer timerInstance = new Timer(); 27 | 28 | public static Timer getInstance() 29 | { 30 | if(timerInstance == null) 31 | { 32 | timerInstance = new Timer(); 33 | } 34 | return timerInstance; 35 | } 36 | 37 | private Timer() 38 | { 39 | systemProperties = ConfigureManager.getInstance().getSystemConfig(); 40 | launch(); 41 | } 42 | 43 | // 初始化配置 44 | private void launch() 45 | { 46 | if( ! isLaunch && schedulerService == null) 47 | { 48 | schedulerService = Executors.newScheduledThreadPool( 49 | Integer.valueOf(systemProperties.getProperty("task_initialize_pool"))); 50 | } 51 | } 52 | 53 | /** 54 | * 55 | * @Description: 启动一个只运行一次的任务 56 | * @param task 57 | * @param delay 等待delay时间之后再执行 58 | * @param unit 59 | * @return 60 | */ 61 | public ScheduledFuture submitOneShotTask(Runnable task, long delay, TimeUnit unit) 62 | { 63 | ScheduledFuture scheduler = schedulerService.schedule(task, delay, unit); 64 | return scheduler; 65 | } 66 | 67 | /** 68 | * 69 | * @Description: 启动一个固定延迟周期执行的脚本, 70 | * 指上一次执行结束之后延迟period时间之后再执行 71 | * 如initialDelay = 1; delay = 3; unit = second; 执行时间固定需要2秒 72 | * 从time=0开始执行的时间应该是1, 6, 11, 16.... 73 | * @param task 74 | * @param initialDelay 75 | * @param period 76 | * @param unit 77 | * @return 78 | */ 79 | public ScheduledFuture submitFixedRateTask(Runnable task, long initialDelay, long period, TimeUnit unit) 80 | { 81 | ScheduledFuture scheduler = schedulerService.scheduleAtFixedRate(task, initialDelay, period, unit); 82 | return scheduler; 83 | } 84 | 85 | /** 86 | * 87 | * @Description: 启动一个固定周期执行的脚本,不管上一个任务执行多久, 88 | * 下一个任务都是在上一个开始执行的delay时间之后执行 89 | * 如initialDelay = 1; delay = 3; unit = second; 执行时间固定需要2秒 90 | * 从time=0开始执行的时间应该是1, 4, 7, 10.... 91 | * @param task 92 | * @param initialDelay 93 | * @param delay 94 | * @param unit 95 | * @return 96 | */ 97 | public ScheduledFuture submitFixedDelayTask(Runnable task, long initialDelay, long delay, TimeUnit unit) 98 | { 99 | ScheduledFuture scheduler = schedulerService.scheduleWithFixedDelay(task, initialDelay, delay, unit); 100 | return scheduler; 101 | } 102 | 103 | /** 104 | * @Description: 关闭所有任务 105 | */ 106 | public void shutDown() 107 | { 108 | if(schedulerService != null) 109 | { 110 | schedulerService.shutdown(); 111 | } 112 | } 113 | 114 | /** 115 | * @Description: 关闭所有任务 116 | */ 117 | public void shutDownNow() 118 | { 119 | if(schedulerService != null) 120 | { 121 | schedulerService.shutdownNow(); 122 | } 123 | } 124 | 125 | 126 | } -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/timer/WorkerInfoReloader.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.timer; 2 | 3 | /** 4 | * 5 | * @Description: 配置实时更新的类 6 | * @author shitou - shitou[at]mogujie.com 7 | * @date 2013-7-22 下午2:54:08 8 | * 9 | */ 10 | //public class WorkerInfoReloader implements Runnable { 11 | // private Logger logger = 12 | // LoggerFactory.getLogger(WorkerInfoReloader.class); 13 | // @Override 14 | // public void run() 15 | // { 16 | // logger.info("reload worker info"); 17 | // //重载所有的配置 18 | // boolean isSuccess = InternalDataModel.getInstance().refreshUserList(); 19 | // if(!isSuccess) { 20 | // logger.error("reload worker info list fail"); 21 | // } 22 | // logger.info("reload worker info list success"); 23 | // } 24 | 25 | // public void recorectData() { 26 | // List groupList = new ArrayList(); 27 | // DBManager dbManager = DBManager.getInstance(); 28 | // Connection conn = dbManager.getConnection(DBPoolName.macim_slave); 29 | // PreparedStatement statement = null; 30 | // ResultSet rs = null; 31 | // CounterModel cm = CounterModel.getInstance(); 32 | // try { 33 | // String sql = "select * from IMGroupRelation where " + 34 | // "status = 1 and groupType = 2 order by updated desc, id desc"; 35 | // statement = conn.prepareStatement(sql); 36 | // rs = statement.executeQuery(); 37 | // GroupRelation gr = null; 38 | // while(rs.next()) { 39 | // gr = new GroupRelation(); 40 | // gr.setGroupId(rs.getInt("groupId")); 41 | // gr.setUserId(rs.getInt("userId")); 42 | // groupList.add(gr); 43 | // } 44 | // int size = groupList.size(); 45 | // logger.info("size: " + size); 46 | // for(int i = 0; i < size; i++) { 47 | // gr = groupList.get(i); 48 | // Map grcnt = cm.getUserGroupUnreadCount(gr.getUserId(), 49 | // new int[]{gr.getGroupId()}); 50 | // GroupMessage[] gm = 51 | // MessageModel.getInstance().getGroupMessages(gr.getGroupId(), 0, 1); 52 | // logger.info("crt: " + gm[0].getCreated() + ", grcnt: " + grcnt); 53 | // if(gr.getUserId() == 9822376 && grcnt.get(gr.getGroupId()) > 0 && 54 | // gm[0].getCreated() > 1400752800) { 55 | // // cm.clearUserGroupCounter(gr.getUserId(), gr.getGroupId()); 56 | // logger.info("清除消息: userId = " + gr.getUserId() 57 | // + " , groupId = " + gr.getGroupId() + ", cnt=" + 58 | // grcnt.get(gr.getGroupId())); 59 | // } 60 | // } 61 | // } catch (SQLException e) { 62 | // logger.error("", e); 63 | // } finally { 64 | // dbManager.release(DBPoolName.macim_slave, conn, statement, rs); 65 | // } 66 | // } 67 | // } 68 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/util/MoguArrayUtil.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.util; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class MoguArrayUtil { 7 | 8 | private static MoguArrayUtil instance = new MoguArrayUtil(); 9 | 10 | public static MoguArrayUtil getInstance() 11 | { 12 | if(instance == null) 13 | { 14 | synchronized(instance) { 15 | instance = new MoguArrayUtil(); 16 | } 17 | } 18 | return instance; 19 | } 20 | 21 | 22 | public int[] arrayUnique(int[] intArray) { 23 | Set intSet = new HashSet(); 24 | int intVal; 25 | int length = intArray.length; 26 | for(int i = 0; i < length; i++) { 27 | intVal = intArray[i]; 28 | if(!intSet.contains(intVal)) { 29 | intSet.add(intVal); 30 | } 31 | } 32 | Integer[] uniqArray = new Integer[intSet.size()]; 33 | intSet.toArray(uniqArray); 34 | int[] ints = new int[uniqArray.length]; 35 | for(int i = 0; i < uniqArray.length; i++) { 36 | ints[i] = uniqArray[i]; 37 | } 38 | return ints; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/src/main/java/com/mogujie/ares/util/MoguByteUtil.java: -------------------------------------------------------------------------------- 1 | package com.mogujie.ares.util; 2 | 3 | public class MoguByteUtil { 4 | 5 | private static MoguByteUtil instance = new MoguByteUtil(); 6 | 7 | public static MoguByteUtil getInstance() 8 | { 9 | if(instance == null) 10 | { 11 | synchronized(instance) { 12 | instance = new MoguByteUtil(); 13 | } 14 | } 15 | return instance; 16 | } 17 | 18 | public int convert2Int(byte[] bytes) { 19 | return (((int)bytes[0]) << 24) + (((int)bytes[1]) << 16) + (((int)bytes[2]) << 8) + bytes[3]; 20 | } 21 | 22 | public byte[] getBytes(int value) { 23 | byte[] bytes = new byte[4]; 24 | bytes[0] = (byte)(value >>> 24);//取最高8位放到0下标 25 | bytes[1] = (byte)(value >>> 16);//取次高8为放到1下标 26 | bytes[2] = (byte)(value >>> 8); //取次低8位放到2下标 27 | bytes[3] = (byte)(value ); //取最低8位放到3下标 28 | return bytes; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/src/main/resources/cache-online.properties: -------------------------------------------------------------------------------- 1 | instances=counter,unread,group_counter,business 2 | #消息计数器的redis 3 | counter_host=0.0.0.0 4 | counter_port=6379 5 | counter_db=0 6 | #未读消息计数器的redis 7 | unread_host=0.0.0.0 8 | unread_port=6379 9 | unread_db=1 10 | 11 | #群消息计数,未读消息和总计数都在这里 12 | group_counter_host=0.0.0.0 13 | group_counter_port=6379 14 | group_counter_db=2 15 | 16 | #IM 业务 cache 17 | business_host=0.0.0.0 18 | business_port=6379 19 | business_db=3 20 | -------------------------------------------------------------------------------- /java/src/main/resources/common-online.properties: -------------------------------------------------------------------------------- 1 | com.mogujie.ares.config.file.serverurl=http://0.0.0.0:8600/ 2 | -------------------------------------------------------------------------------- /java/src/main/resources/db-online.properties: -------------------------------------------------------------------------------- 1 | instances=macim_master,macim_slave 2 | # macim master库 3 | macim_master_url=jdbc:mysql://0.0.0.0/im 4 | macim_master_port=3306 5 | macim_master_username=im 6 | macim_master_password=im123 7 | # macim slave库 8 | macim_slave_url=jdbc:mysql://0.0.0.0/im 9 | macim_master_port=3306 10 | macim_slave_username=im 11 | macim_slave_password=im123 12 | -------------------------------------------------------------------------------- /java/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | System.out 7 | 8 | %d{HH:mm:ss.SSS} [%p] [%c] - %m%n 9 | 10 | 11 | INFO 12 | 13 | 14 | 15 | true 16 | logs/mogutalk.log 17 | 18 | logs/%d{yyyyMMdd}/mogutalk.log 19 | 60 20 | 21 | 22 | %d{HH:mm:ss.SSS} [%p] [%c] - %m%n 23 | 24 | 25 | INFO 26 | 27 | 28 | 29 | true 30 | logs/mogutalk-error.log 31 | 32 | logs/%d{yyyyMMdd}/mogutalk-error.log 33 | 60 34 | 35 | 36 | %d{HH:mm:ss.SSS} [%p] [%c] - %m%n 37 | 38 | 39 | ERROR 40 | 41 | 42 | 43 | true 44 | logs/mogutalk-nonefiltered.log 45 | 46 | logs/%d{yyyyMMdd}/mogutalk-nonefiltered.log 47 | 60 48 | 49 | 50 | %d{HH:mm:ss.SSS} [%p] [%c] - %m%n 51 | 52 | 53 | 54 | 55 | 56 | true 57 | logs/mogutalk-connection.log 58 | 59 | logs/%d{yyyyMMdd}/mogutalk-connection.log 60 | 60 61 | 62 | 63 | %d{HH:mm:ss.SSS} [%p] [%c] - %m%n 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /java/src/main/resources/system.properties: -------------------------------------------------------------------------------- 1 | mcrypt_salt=tt vs TT ? 2 | task_initialize_pool=3 3 | 4 | com.mogujie.ares.config.file.db=${config.file.db} 5 | com.mogujie.ares.config.file.cache=${config.file.cache} 6 | com.mogujie.ares.config.file.route=route.xml 7 | com.mogujie.ares.config.file.timer=timer.xml 8 | com.mogujie.ares.config.file.common=${config.commom} 9 | -------------------------------------------------------------------------------- /java/src/main/resources/timer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | com.mogujie.ares.timer.ConfigureReloadTask 5 | 0 6 | rateTask 7 | 3 8 | 3 9 | 10 | 11 | --------------------------------------------------------------------------------