正在显示
1 个修改的文件
包含
147 行增加
和
0 行删除
src/server/spserver/testdispatcher.cpp
0 → 100644
1 | +/* | ||
2 | + * Copyright 2007 Stephen Liu | ||
3 | + * For license terms, see the file COPYING along with this library. | ||
4 | + */ | ||
5 | + | ||
6 | +#include <stdio.h> | ||
7 | +#include <syslog.h> | ||
8 | +#include <string.h> | ||
9 | +#include <unistd.h> | ||
10 | +#include <time.h> | ||
11 | + | ||
12 | +#include <sys/types.h> | ||
13 | +#include <sys/socket.h> | ||
14 | +#include <netinet/in.h> | ||
15 | + | ||
16 | +#include "spdispatcher.hpp" | ||
17 | +#include "sphandler.hpp" | ||
18 | +#include "spresponse.hpp" | ||
19 | +#include "sprequest.hpp" | ||
20 | +#include "spbuffer.hpp" | ||
21 | +#include "spmsgdecoder.hpp" | ||
22 | +#include "speventcb.hpp" | ||
23 | +#include "spioutils.hpp" | ||
24 | + | ||
25 | +class SP_EchoHandler : public SP_Handler { | ||
26 | +public: | ||
27 | + SP_EchoHandler(){} | ||
28 | + virtual ~SP_EchoHandler(){} | ||
29 | + | ||
30 | + // return -1 : terminate session, 0 : continue | ||
31 | + virtual int start( SP_Request * request, SP_Response * response ) { | ||
32 | + request->setMsgDecoder( new SP_LineMsgDecoder() ); | ||
33 | + response->getReply()->getMsg()->append( | ||
34 | + "Welcome to line echo dispatcher, enter 'quit' to quit.\r\n" ); | ||
35 | + | ||
36 | + return 0; | ||
37 | + } | ||
38 | + | ||
39 | + // return -1 : terminate session, 0 : continue | ||
40 | + virtual int handle( SP_Request * request, SP_Response * response ) { | ||
41 | + SP_LineMsgDecoder * decoder = (SP_LineMsgDecoder*)request->getMsgDecoder(); | ||
42 | + | ||
43 | + if( 0 != strcasecmp( (char*)decoder->getMsg(), "quit" ) ) { | ||
44 | + response->getReply()->getMsg()->append( (char*)decoder->getMsg() ); | ||
45 | + response->getReply()->getMsg()->append( "\r\n" ); | ||
46 | + return 0; | ||
47 | + } else { | ||
48 | + response->getReply()->getMsg()->append( "Byebye\r\n" ); | ||
49 | + return -1; | ||
50 | + } | ||
51 | + } | ||
52 | + | ||
53 | + virtual void error( SP_Response * response ) {} | ||
54 | + | ||
55 | + virtual void timeout( SP_Response * response ) {} | ||
56 | + | ||
57 | + virtual void close() {} | ||
58 | +}; | ||
59 | + | ||
60 | +class SP_EchoTimerHandler : public SP_TimerHandler { | ||
61 | +public: | ||
62 | + SP_EchoTimerHandler(){ | ||
63 | + mCount = 1; | ||
64 | + } | ||
65 | + | ||
66 | + virtual ~SP_EchoTimerHandler(){} | ||
67 | + | ||
68 | + // return -1 : terminate timer, 0 : continue | ||
69 | + virtual int handle( SP_Response * response, struct timeval * timeout ) { | ||
70 | + syslog( LOG_NOTICE, "time = %li, call timer handler", time( NULL ) ); | ||
71 | + | ||
72 | + if( ++mCount >= 10 ) { | ||
73 | + syslog( LOG_NOTICE, "stop timer" ); | ||
74 | + return -1; | ||
75 | + } else { | ||
76 | + syslog( LOG_NOTICE, "set timer to %d seconds later", mCount ); | ||
77 | + timeout->tv_sec = mCount; | ||
78 | + return 0; | ||
79 | + } | ||
80 | + } | ||
81 | + | ||
82 | +private: | ||
83 | + int mCount; | ||
84 | +}; | ||
85 | + | ||
86 | +int main( int argc, char * argv[] ) | ||
87 | +{ | ||
88 | + int port = 3333, maxThreads = 10; | ||
89 | + | ||
90 | + extern char *optarg ; | ||
91 | + int c ; | ||
92 | + | ||
93 | + while( ( c = getopt ( argc, argv, "p:t:v" )) != EOF ) { | ||
94 | + switch ( c ) { | ||
95 | + case 'p' : | ||
96 | + port = atoi( optarg ); | ||
97 | + break; | ||
98 | + case 't': | ||
99 | + maxThreads = atoi( optarg ); | ||
100 | + break; | ||
101 | + case '?' : | ||
102 | + case 'v' : | ||
103 | + printf( "Usage: %s [-p <port>] [-t <threads>]\n", argv[0] ); | ||
104 | + exit( 0 ); | ||
105 | + } | ||
106 | + } | ||
107 | + | ||
108 | + openlog( "testdispatcher", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); | ||
109 | + | ||
110 | + int maxConnections = 100, reqQueueSize = 10; | ||
111 | + const char * refusedMsg = "System busy, try again later."; | ||
112 | + | ||
113 | + int listenFd = -1; | ||
114 | + if( 0 == SP_IOUtils::tcpListen( "", port, &listenFd ) ) { | ||
115 | + SP_Dispatcher dispatcher( new SP_DefaultCompletionHandler(), maxThreads ); | ||
116 | + dispatcher.dispatch(); | ||
117 | + | ||
118 | + struct timeval timeout; | ||
119 | + memset( &timeout, 0, sizeof( timeout ) ); | ||
120 | + timeout.tv_sec = 1; | ||
121 | + | ||
122 | + dispatcher.push( &timeout, new SP_EchoTimerHandler() ); | ||
123 | + | ||
124 | + for( ; ; ) { | ||
125 | + struct sockaddr_in addr; | ||
126 | + socklen_t socklen = sizeof( addr ); | ||
127 | + int fd = accept( listenFd, (struct sockaddr*)&addr, &socklen ); | ||
128 | + | ||
129 | + if( fd > 0 ) { | ||
130 | + if( dispatcher.getSessionCount() >= maxConnections | ||
131 | + || dispatcher.getReqQueueLength() >= reqQueueSize ) { | ||
132 | + write( fd, refusedMsg, strlen( refusedMsg ) ); | ||
133 | + close( fd ); | ||
134 | + } else { | ||
135 | + dispatcher.push( fd, new SP_EchoHandler() ); | ||
136 | + } | ||
137 | + } else { | ||
138 | + break; | ||
139 | + } | ||
140 | + } | ||
141 | + } | ||
142 | + | ||
143 | + closelog(); | ||
144 | + | ||
145 | + return 0; | ||
146 | +} | ||
147 | + |
请
注册
或
登录
后发表评论