{
32 | private static final int CRLF_SHORT = (CR << 8) | LF;
33 |
34 | @Override
35 | public boolean acceptOutboundMessage(final Object msg)
36 | throws Exception {
37 | return super.acceptOutboundMessage(msg) && ((msg instanceof HttpRequest) || (msg instanceof HttpResponse));
38 | }
39 |
40 | @Override
41 | protected void encodeInitialLine(final ByteBuf buf, final HttpMessage message)
42 | throws Exception {
43 | if (message instanceof HttpRequest) {
44 | HttpRequest request = (HttpRequest) message;
45 | ByteBufUtil.copy(request.method().asciiName(), buf);
46 | buf.writeByte(SP);
47 | buf.writeCharSequence(request.uri(), CharsetUtil.UTF_8);
48 | buf.writeByte(SP);
49 | buf.writeCharSequence(request.protocolVersion().toString(), CharsetUtil.US_ASCII);
50 | ByteBufUtil.writeShortBE(buf, CRLF_SHORT);
51 | } else if (message instanceof HttpResponse) {
52 | HttpResponse response = (HttpResponse) message;
53 | buf.writeCharSequence(response.protocolVersion().toString(), CharsetUtil.US_ASCII);
54 | buf.writeByte(SP);
55 | ByteBufUtil.copy(response.status().codeAsText(), buf);
56 | buf.writeByte(SP);
57 | buf.writeCharSequence(response.status().reasonPhrase(), CharsetUtil.US_ASCII);
58 | ByteBufUtil.writeShortBE(buf, CRLF_SHORT);
59 | } else {
60 | throw new UnsupportedMessageTypeException("Unsupported type "
61 | + StringUtil.simpleClassName(message));
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/sip/SipHeaderNames.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | package com.wangdxh.sip;
18 |
19 | import io.netty.handler.codec.http.HttpHeaderNames;
20 | import io.netty.util.AsciiString;
21 |
22 | /**
23 | * Standard RTSP header names.
24 | *
25 | * These are all defined as lowercase to support HTTP/2 requirements while also not
26 | * violating RTSP/1.x requirements. New header names should always be lowercase.
27 | */
28 | public final class SipHeaderNames {
29 |
30 | public static final AsciiString FROM = HttpHeaderNames.FROM;
31 | public static final AsciiString TO = AsciiString.cached("to");
32 | public static final AsciiString CALL_ID = AsciiString.cached("call-id");
33 | public static final AsciiString MAX_FORWORDS = AsciiString.cached("max-forwords");
34 | public static final AsciiString AUTHORIZATION = HttpHeaderNames.AUTHORIZATION;
35 | public static final AsciiString CONTENT_LENGTH = HttpHeaderNames.CONTENT_LENGTH;
36 | public static final AsciiString CONTENT_TYPE = HttpHeaderNames.CONTENT_TYPE;
37 | public static final AsciiString CSEQ = AsciiString.cached("cseq");
38 | public static final AsciiString USER_AGENT = HttpHeaderNames.USER_AGENT;
39 | public static final AsciiString VIA = HttpHeaderNames.VIA;
40 | public static final AsciiString WWW_AUTHENTICATE = HttpHeaderNames.WWW_AUTHENTICATE;
41 |
42 | private SipHeaderNames() { }
43 | }
44 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/sip/SipHeaderValues.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | package com.wangdxh.sip;
18 |
19 | import io.netty.handler.codec.http.HttpHeaderValues;
20 | import io.netty.util.AsciiString;
21 |
22 | /**
23 | * Standard RTSP header names.
24 | */
25 | public final class SipHeaderValues {
26 |
27 | public static final AsciiString APPEND = AsciiString.cached("append");
28 |
29 | public static final AsciiString CHARSET = HttpHeaderValues.CHARSET;
30 |
31 |
32 | private SipHeaderValues() { }
33 | }
34 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/sip/SipMethods.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 | package com.wangdxh.sip;
17 |
18 | import io.netty.handler.codec.http.HttpMethod;
19 |
20 | import java.util.HashMap;
21 | import java.util.Map;
22 |
23 | /**
24 | * The request getMethod of RTSP.
25 | */
26 | public final class SipMethods {
27 |
28 | /**
29 | * The OPTIONS getMethod represents a request for information about the communication options
30 | * available on the request/response chain identified by the Request-URI. This getMethod allows
31 | * the client to determine the options and/or requirements associated with a resource, or the
32 | * capabilities of a server, without implying a resource action or initiating a resource
33 | * retrieval.
34 | */
35 | public static final HttpMethod INVITE = new HttpMethod("INVITE");
36 |
37 | /**
38 | * The DESCRIBE getMethod retrieves the description of a presentation or
39 | * media object identified by the request URL from a server.
40 | */
41 | public static final HttpMethod ACK = new HttpMethod("ACK");
42 |
43 | /**
44 | * The ANNOUNCE posts the description of a presentation or media object
45 | * identified by the request URL to a server, or updates the client-side
46 | * session description in real-time.
47 | */
48 | public static final HttpMethod INFO = new HttpMethod("INFO");
49 |
50 | /**
51 | * The SETUP request for a URI specifies the transport mechanism to be
52 | * used for the streamed media.
53 | */
54 | public static final HttpMethod MESSAGE = new HttpMethod("MESSAGE");
55 |
56 | /**
57 | * The PLAY getMethod tells the server to start sending data via the
58 | * mechanism specified in SETUP.
59 | */
60 | public static final HttpMethod BYE = new HttpMethod("BYE");
61 |
62 | /**
63 | * The PAUSE request causes the stream delivery to be interrupted
64 | * (halted) temporarily.
65 | */
66 | public static final HttpMethod REGISTER = new HttpMethod("REGISTER");
67 |
68 |
69 | private static final Map methodMap = new HashMap();
70 |
71 | static {
72 | methodMap.put(INVITE.toString(), INVITE);
73 | methodMap.put(INFO.toString(), INFO);
74 | methodMap.put(ACK.toString(), ACK);
75 | methodMap.put(BYE.toString(), BYE);
76 | methodMap.put(REGISTER.toString(), REGISTER);
77 | methodMap.put(MESSAGE.toString(), MESSAGE);
78 | }
79 |
80 | /**
81 | * Returns the {@link HttpMethod} represented by the specified name.
82 | * If the specified name is a standard RTSP getMethod name, a cached instance
83 | * will be returned. Otherwise, a new instance will be returned.
84 | */
85 | public static HttpMethod valueOf(String name) {
86 | if (name == null) {
87 | throw new NullPointerException("name");
88 | }
89 |
90 | name = name.trim().toUpperCase();
91 | if (name.isEmpty()) {
92 | throw new IllegalArgumentException("empty name");
93 | }
94 |
95 | HttpMethod result = methodMap.get(name);
96 | if (result != null) {
97 | return result;
98 | } else {
99 | return new HttpMethod(name);
100 | }
101 | }
102 |
103 | private SipMethods() {
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/sip/SipResponseStatuses.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 | package com.wangdxh.sip;
17 |
18 | import io.netty.handler.codec.http.HttpResponseStatus;
19 |
20 | /**
21 | * The getStatus code and its description of a RTSP response.
22 | */
23 | public final class SipResponseStatuses {
24 |
25 | /**
26 | * 100 Continue
27 | */
28 | public static final HttpResponseStatus CONTINUE = HttpResponseStatus.CONTINUE;
29 |
30 | /**
31 | * 200 OK
32 | */
33 | public static final HttpResponseStatus OK = HttpResponseStatus.OK;
34 |
35 | /**
36 | * 201 Created
37 | */
38 | public static final HttpResponseStatus CREATED = HttpResponseStatus.CREATED;
39 |
40 | /**
41 | * 250 Low on Storage Space
42 | */
43 | public static final HttpResponseStatus LOW_STORAGE_SPACE = new HttpResponseStatus(
44 | 250, "Low on Storage Space");
45 |
46 | /**
47 | * 300 Multiple Choices
48 | */
49 | public static final HttpResponseStatus MULTIPLE_CHOICES = HttpResponseStatus.MULTIPLE_CHOICES;
50 |
51 | /**
52 | * 301 Moved Permanently
53 | */
54 | public static final HttpResponseStatus MOVED_PERMANENTLY = HttpResponseStatus.MOVED_PERMANENTLY;
55 |
56 | /**
57 | * 302 Moved Temporarily
58 | */
59 | public static final HttpResponseStatus MOVED_TEMPORARILY = new HttpResponseStatus(
60 | 302, "Moved Temporarily");
61 | /**
62 | * 304 Not Modified
63 | */
64 | public static final HttpResponseStatus NOT_MODIFIED = HttpResponseStatus.NOT_MODIFIED;
65 |
66 | /**
67 | * 305 Use Proxy
68 | */
69 | public static final HttpResponseStatus USE_PROXY = HttpResponseStatus.USE_PROXY;
70 |
71 | /**
72 | * 400 Bad Request
73 | */
74 | public static final HttpResponseStatus BAD_REQUEST = HttpResponseStatus.BAD_REQUEST;
75 |
76 | /**
77 | * 401 Unauthorized
78 | */
79 | public static final HttpResponseStatus UNAUTHORIZED = HttpResponseStatus.UNAUTHORIZED;
80 |
81 | /**
82 | * 402 Payment Required
83 | */
84 | public static final HttpResponseStatus PAYMENT_REQUIRED = HttpResponseStatus.PAYMENT_REQUIRED;
85 |
86 | /**
87 | * 403 Forbidden
88 | */
89 | public static final HttpResponseStatus FORBIDDEN = HttpResponseStatus.FORBIDDEN;
90 |
91 | /**
92 | * 404 Not Found
93 | */
94 | public static final HttpResponseStatus NOT_FOUND = HttpResponseStatus.NOT_FOUND;
95 |
96 | /**
97 | * 405 Method Not Allowed
98 | */
99 | public static final HttpResponseStatus METHOD_NOT_ALLOWED = HttpResponseStatus.METHOD_NOT_ALLOWED;
100 |
101 | /**
102 | * 406 Not Acceptable
103 | */
104 | public static final HttpResponseStatus NOT_ACCEPTABLE = HttpResponseStatus.NOT_ACCEPTABLE;
105 |
106 | /**
107 | * 407 Proxy Authentication Required
108 | */
109 | public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED =
110 | HttpResponseStatus.PROXY_AUTHENTICATION_REQUIRED;
111 |
112 | /**
113 | * 408 Request Timeout
114 | */
115 | public static final HttpResponseStatus REQUEST_TIMEOUT = HttpResponseStatus.REQUEST_TIMEOUT;
116 |
117 | /**
118 | * 410 Gone
119 | */
120 | public static final HttpResponseStatus GONE = HttpResponseStatus.GONE;
121 |
122 | /**
123 | * 411 Length Required
124 | */
125 | public static final HttpResponseStatus LENGTH_REQUIRED = HttpResponseStatus.LENGTH_REQUIRED;
126 |
127 | /**
128 | * 412 Precondition Failed
129 | */
130 | public static final HttpResponseStatus PRECONDITION_FAILED = HttpResponseStatus.PRECONDITION_FAILED;
131 |
132 | /**
133 | * 413 Request Entity Too Large
134 | */
135 | public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE;
136 |
137 | /**
138 | * 414 Request-URI Too Long
139 | */
140 | public static final HttpResponseStatus REQUEST_URI_TOO_LONG = HttpResponseStatus.REQUEST_URI_TOO_LONG;
141 |
142 | /**
143 | * 415 Unsupported Media Type
144 | */
145 | public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE;
146 |
147 | /**
148 | * 451 Parameter Not Understood
149 | */
150 | public static final HttpResponseStatus PARAMETER_NOT_UNDERSTOOD = new HttpResponseStatus(
151 | 451, "Parameter Not Understood");
152 |
153 | /**
154 | * 452 Conference Not Found
155 | */
156 | public static final HttpResponseStatus CONFERENCE_NOT_FOUND = new HttpResponseStatus(
157 | 452, "Conference Not Found");
158 |
159 | /**
160 | * 453 Not Enough Bandwidth
161 | */
162 | public static final HttpResponseStatus NOT_ENOUGH_BANDWIDTH = new HttpResponseStatus(
163 | 453, "Not Enough Bandwidth");
164 |
165 | /**
166 | * 454 Session Not Found
167 | */
168 | public static final HttpResponseStatus SESSION_NOT_FOUND = new HttpResponseStatus(
169 | 454, "Session Not Found");
170 |
171 | /**
172 | * 455 Method Not Valid in This State
173 | */
174 | public static final HttpResponseStatus METHOD_NOT_VALID = new HttpResponseStatus(
175 | 455, "Method Not Valid in This State");
176 |
177 | /**
178 | * 456 Header Field Not Valid for Resource
179 | */
180 | public static final HttpResponseStatus HEADER_FIELD_NOT_VALID = new HttpResponseStatus(
181 | 456, "Header Field Not Valid for Resource");
182 |
183 | /**
184 | * 457 Invalid Range
185 | */
186 | public static final HttpResponseStatus INVALID_RANGE = new HttpResponseStatus(
187 | 457, "Invalid Range");
188 |
189 | /**
190 | * 458 Parameter Is Read-Only
191 | */
192 | public static final HttpResponseStatus PARAMETER_IS_READONLY = new HttpResponseStatus(
193 | 458, "Parameter Is Read-Only");
194 |
195 | /**
196 | * 459 Aggregate operation not allowed
197 | */
198 | public static final HttpResponseStatus AGGREGATE_OPERATION_NOT_ALLOWED = new HttpResponseStatus(
199 | 459, "Aggregate operation not allowed");
200 |
201 | /**
202 | * 460 Only Aggregate operation allowed
203 | */
204 | public static final HttpResponseStatus ONLY_AGGREGATE_OPERATION_ALLOWED = new HttpResponseStatus(
205 | 460, "Only Aggregate operation allowed");
206 |
207 | /**
208 | * 461 Unsupported transport
209 | */
210 | public static final HttpResponseStatus UNSUPPORTED_TRANSPORT = new HttpResponseStatus(
211 | 461, "Unsupported transport");
212 |
213 | /**
214 | * 462 Destination unreachable
215 | */
216 | public static final HttpResponseStatus DESTINATION_UNREACHABLE = new HttpResponseStatus(
217 | 462, "Destination unreachable");
218 |
219 | /**
220 | * 463 Key management failure
221 | */
222 | public static final HttpResponseStatus KEY_MANAGEMENT_FAILURE = new HttpResponseStatus(
223 | 463, "Key management failure");
224 |
225 | /**
226 | * 500 Internal Server Error
227 | */
228 | public static final HttpResponseStatus INTERNAL_SERVER_ERROR = HttpResponseStatus.INTERNAL_SERVER_ERROR;
229 |
230 | /**
231 | * 501 Not Implemented
232 | */
233 | public static final HttpResponseStatus NOT_IMPLEMENTED = HttpResponseStatus.NOT_IMPLEMENTED;
234 |
235 | /**
236 | * 502 Bad Gateway
237 | */
238 | public static final HttpResponseStatus BAD_GATEWAY = HttpResponseStatus.BAD_GATEWAY;
239 |
240 | /**
241 | * 503 Service Unavailable
242 | */
243 | public static final HttpResponseStatus SERVICE_UNAVAILABLE = HttpResponseStatus.SERVICE_UNAVAILABLE;
244 |
245 | /**
246 | * 504 Gateway Timeout
247 | */
248 | public static final HttpResponseStatus GATEWAY_TIMEOUT = HttpResponseStatus.GATEWAY_TIMEOUT;
249 |
250 | /**
251 | * 505 RTSP Version not supported
252 | */
253 | public static final HttpResponseStatus RTSP_VERSION_NOT_SUPPORTED = new HttpResponseStatus(
254 | 505, "RTSP Version not supported");
255 |
256 | /**
257 | * 551 Option not supported
258 | */
259 | public static final HttpResponseStatus OPTION_NOT_SUPPORTED = new HttpResponseStatus(
260 | 551, "Option not supported");
261 |
262 | /**
263 | * Returns the {@link HttpResponseStatus} represented by the specified code.
264 | * If the specified code is a standard RTSP getStatus code, a cached instance
265 | * will be returned. Otherwise, a new instance will be returned.
266 | */
267 | public static HttpResponseStatus valueOf(int code) {
268 | switch (code) {
269 | case 250: return LOW_STORAGE_SPACE;
270 | case 302: return MOVED_TEMPORARILY;
271 | case 451: return PARAMETER_NOT_UNDERSTOOD;
272 | case 452: return CONFERENCE_NOT_FOUND;
273 | case 453: return NOT_ENOUGH_BANDWIDTH;
274 | case 454: return SESSION_NOT_FOUND;
275 | case 455: return METHOD_NOT_VALID;
276 | case 456: return HEADER_FIELD_NOT_VALID;
277 | case 457: return INVALID_RANGE;
278 | case 458: return PARAMETER_IS_READONLY;
279 | case 459: return AGGREGATE_OPERATION_NOT_ALLOWED;
280 | case 460: return ONLY_AGGREGATE_OPERATION_ALLOWED;
281 | case 461: return UNSUPPORTED_TRANSPORT;
282 | case 462: return DESTINATION_UNREACHABLE;
283 | case 463: return KEY_MANAGEMENT_FAILURE;
284 | case 505: return RTSP_VERSION_NOT_SUPPORTED;
285 | case 551: return OPTION_NOT_SUPPORTED;
286 | default: return HttpResponseStatus.valueOf(code);
287 | }
288 | }
289 |
290 | private SipResponseStatuses() {
291 | }
292 | }
293 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/sip/SipVersions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 | package com.wangdxh.sip;
17 |
18 | import io.netty.handler.codec.http.HttpVersion;
19 |
20 | /**
21 | * The version of SIP.
22 | */
23 | public final class SipVersions {
24 |
25 | /**
26 | * SIP/2.0
27 | */
28 | public static final HttpVersion SIP_2_0 = new HttpVersion("SIP", 2, 0, true);
29 |
30 | /**
31 | * Returns an existing or new {@link HttpVersion} instance which matches to
32 | * the specified RTSP version string. If the specified {@code text} is
33 | * equal to {@code "SIP/2.0"}, {@link #SIP_2_0} will be returned.
34 | * Otherwise, a new {@link HttpVersion} instance will be returned.
35 | */
36 | public static HttpVersion valueOf(String text) {
37 | if (text == null) {
38 | throw new NullPointerException("text");
39 | }
40 |
41 | text = text.trim().toUpperCase();
42 | if ("SIP/2.0".equals(text)) {
43 | return SIP_2_0;
44 | }
45 |
46 | return new HttpVersion(text, true);
47 | }
48 |
49 | private SipVersions() {
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/ssl/SSLContextFactory.java:
--------------------------------------------------------------------------------
1 | package com.wangdxh.ssl;
2 |
3 | // C:\Users\Administrator>keytool -genkey -keysize 2048 -validity 365 -keyalg RSA -dname "CN=localhost" -keypass hsc123
4 | // -storepass hsc123 -keystore c:\local.jks
5 |
6 | import javax.net.ssl.KeyManagerFactory;
7 | import javax.net.ssl.SSLContext;
8 | import java.io.FileInputStream;
9 | import java.security.KeyStore;
10 |
11 | public class SSLContextFactory
12 | {
13 | public static SSLContext getSslContext() throws Exception
14 | {
15 | char[] passArray = "hsc123".toCharArray();
16 | SSLContext sslContext = SSLContext.getInstance("TLSv1");
17 |
18 | KeyStore ks = KeyStore.getInstance("JKS");
19 | //加载keytool 生成的文件
20 | FileInputStream inputStream = new FileInputStream("c:\\local.jks");
21 | ks.load(inputStream, passArray);
22 | KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
23 | kmf.init(ks, passArray);
24 | sslContext.init(kmf.getKeyManagers(), null, null);
25 | inputStream.close();
26 | return sslContext;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/streamhub/StreamFrame.java:
--------------------------------------------------------------------------------
1 | package com.wangdxh.streamhub;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.DefaultByteBufHolder;
5 |
6 | public class StreamFrame extends DefaultByteBufHolder
7 | {
8 | public int dwTime;
9 | public boolean bIsKey;
10 | public int streamType;
11 |
12 | public StreamFrame(ByteBuf buf)
13 | {
14 | super(buf);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/streamhub/StreamFrameSink.java:
--------------------------------------------------------------------------------
1 | package com.wangdxh.streamhub;
2 |
3 | public interface StreamFrameSink {
4 | boolean WriteFrame(StreamFrame frame);
5 | void CloseThisClient();
6 | }
7 |
--------------------------------------------------------------------------------
/netty-streamserver/src/main/java/com/wangdxh/streamhub/StreamHub.java:
--------------------------------------------------------------------------------
1 | package com.wangdxh.streamhub;
2 |
3 | import java.util.Map;
4 | import java.util.Set;
5 | import java.util.concurrent.ConcurrentHashMap;
6 |
7 | public class StreamHub {
8 | private static Map> sinkmap = new ConcurrentHashMap<>();
9 |
10 | public static Map GetStream(String name){
11 | if (sinkmap.containsKey(name)){
12 | return sinkmap.get(name);
13 | }
14 | Map map = new ConcurrentHashMap<>();
15 | Map retmap = sinkmap.putIfAbsent(name, map);
16 | return retmap == null ? map : retmap;
17 | }
18 |
19 | public static void EnterStream(String name, StreamFrameSink sink){
20 | GetStream(name).put(sink, sink);
21 | }
22 | public static void LeaveStream(String name, StreamFrameSink sink){
23 | GetStream(name).remove(sink);
24 | }
25 |
26 | public static void WriteFrame(Map map, StreamFrame frame){
27 | //System.out.printf("input thread %s\n", Thread.currentThread().getName());
28 | for(StreamFrameSink key : map.keySet()){
29 | key.WriteFrame(frame);
30 | }
31 | }
32 | public static Set GetStreams()
33 | {
34 | return sinkmap.keySet();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/netty-streamserver/src/test/java/com/wangdxh/AppTest.java:
--------------------------------------------------------------------------------
1 | package com.wangdxh;
2 |
3 | import static org.junit.Assert.assertTrue;
4 |
5 | import org.junit.Test;
6 |
7 | /**
8 | * Unit test for simple App.
9 | */
10 | public class AppTest
11 | {
12 | /**
13 | * Rigorous Test :-)
14 | */
15 | @Test
16 | public void shouldAnswerWithTrue()
17 | {
18 | assertTrue( true );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------