Skip to content

Commit 5f089e6

Browse files
committed
Refactored exterialize and amf in/out handling
1 parent a977ca4 commit 5f089e6

File tree

17 files changed

+467
-350
lines changed

17 files changed

+467
-350
lines changed

common/src/main/java/org/red5/server/net/rtmp/status/RuntimeStatusObject.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,14 @@
77

88
package org.red5.server.net.rtmp.status;
99

10-
import java.io.IOException;
11-
import java.io.ObjectInput;
12-
import java.io.ObjectOutput;
10+
import org.red5.io.amf3.IDataInput;
11+
import org.red5.io.amf3.IDataOutput;
1312

1413
/**
1514
* Runtime status object
1615
*/
1716
public class RuntimeStatusObject extends StatusObject {
1817

19-
/**
20-
* Serializable
21-
*/
22-
private static final long serialVersionUID = 6990998992583246039L;
23-
2418
/**
2519
* Status event details
2620
*/
@@ -109,14 +103,14 @@ public void setDetails(String details) {
109103
}
110104

111105
@Override
112-
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
106+
public void readExternal(IDataInput in) {
113107
super.readExternal(in);
114108
clientid = in.readInt();
115109
details = (String) in.readObject();
116110
}
117111

118112
@Override
119-
public void writeExternal(ObjectOutput out) throws IOException {
113+
public void writeExternal(IDataOutput out) {
120114
super.writeExternal(out);
121115
out.writeInt(clientid);
122116
out.writeObject(details);

common/src/main/java/org/red5/server/net/rtmp/status/Status.java

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,16 @@
77

88
package org.red5.server.net.rtmp.status;
99

10-
import java.io.Externalizable;
11-
import java.io.IOException;
12-
import java.io.ObjectInput;
13-
import java.io.ObjectOutput;
14-
1510
import org.red5.annotations.Anonymous;
16-
import org.red5.io.object.ICustomSerializable;
17-
import org.red5.io.object.Output;
11+
import org.red5.io.amf3.IDataInput;
12+
import org.red5.io.amf3.IDataOutput;
13+
import org.red5.io.amf3.IExternalizable;
1814

1915
/**
2016
* Represents status object that are transferred between server and client
2117
*/
2218
@Anonymous
23-
public class Status implements StatusCodes, ICustomSerializable, Externalizable {
24-
25-
private static final long serialVersionUID = -5501563718489586136L;
19+
public class Status implements StatusCodes, IExternalizable {
2620

2721
/**
2822
* Error constant
@@ -206,36 +200,22 @@ public String toString() {
206200
return "Status: code: " + getCode() + " desc: " + getDescription() + " level: " + getLevel();
207201
}
208202

209-
public void serialize(Output output) {
210-
output.putString("level");
211-
output.writeString(getLevel());
212-
output.putString("code");
213-
output.writeString(getCode());
214-
output.putString("description");
215-
output.writeString(getDescription());
216-
output.putString("details");
217-
if (getDetails() != null) {
218-
output.writeString(getDetails());
219-
} else {
220-
output.writeNull();
221-
}
222-
output.putString("clientid");
223-
output.writeNumber(getClientid());
224-
}
225-
226-
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
203+
@Override
204+
public void readExternal(IDataInput in) {
227205
clientid = (Number) in.readDouble();
228-
code = (String) in.readObject();
229-
description = (String) in.readObject();
230-
details = (String) in.readObject();
231-
level = (String) in.readObject();
206+
code = (String) in.readUTF();
207+
description = (String) in.readUTF();
208+
details = (String) in.readUTF();
209+
level = (String) in.readUTF();
232210
}
233211

234-
public void writeExternal(ObjectOutput out) throws IOException {
212+
@Override
213+
public void writeExternal(IDataOutput out) {
235214
out.writeDouble(clientid.doubleValue());
236-
out.writeObject(code);
237-
out.writeObject(description);
238-
out.writeObject(details);
239-
out.writeObject(level);
215+
out.writeUTF(code);
216+
out.writeUTF(description);
217+
out.writeUTF(details);
218+
out.writeUTF(level);
240219
}
220+
241221
}

common/src/main/java/org/red5/server/net/rtmp/status/StatusObject.java

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,13 @@
77

88
package org.red5.server.net.rtmp.status;
99

10-
import java.io.Externalizable;
11-
import java.io.IOException;
12-
import java.io.ObjectInput;
13-
import java.io.ObjectOutput;
14-
import java.io.Serializable;
1510
import java.util.HashMap;
1611
import java.util.Map;
1712

1813
import org.red5.annotations.Anonymous;
19-
import org.red5.io.object.ICustomSerializable;
20-
import org.red5.io.object.Output;
21-
import org.red5.io.object.Serializer;
14+
import org.red5.io.amf3.IDataInput;
15+
import org.red5.io.amf3.IDataOutput;
16+
import org.red5.io.amf3.IExternalizable;
2217

2318
/**
2419
* Status object that is sent to client with every status event
@@ -27,9 +22,7 @@
2722
* @author Luke Hubbard, Codegent Ltd ([email protected])
2823
*/
2924
@Anonymous
30-
public class StatusObject implements Serializable, ICustomSerializable, Externalizable {
31-
32-
private static final long serialVersionUID = 8817297676191096283L;
25+
public class StatusObject implements IExternalizable {
3326

3427
public static final String ERROR = "error";
3528

@@ -139,10 +132,14 @@ public Object getApplication() {
139132
return application;
140133
}
141134

142-
/** {@inheritDoc} */
143-
@Override
144-
public String toString() {
145-
return String.format("Status code: %s level: %s description: %s", code, level, description);
135+
public void setAdditional(String name, Object value) {
136+
if ("code,level,description,application".indexOf(name) != -1) {
137+
throw new RuntimeException("the name \"" + name + "\" is reserved");
138+
}
139+
if (additional == null) {
140+
additional = new HashMap<>();
141+
}
142+
additional.put(name, value);
146143
}
147144

148145
/**
@@ -154,54 +151,37 @@ public Status asStatus() {
154151
return new Status(getCode(), getLevel(), getDescription());
155152
}
156153

157-
public void setAdditional(String name, Object value) {
158-
if ("code,level,description,application".indexOf(name) != -1) {
159-
throw new RuntimeException("the name \"" + name + "\" is reserved");
160-
}
161-
if (additional == null) {
162-
additional = new HashMap<String, Object>();
163-
}
164-
additional.put(name, value);
165-
}
166-
167-
public void serialize(Output output) {
168-
output.putString("level");
169-
output.writeString(getLevel());
170-
output.putString("code");
171-
output.writeString(getCode());
172-
output.putString("description");
173-
output.writeString(getDescription());
174-
if (application != null) {
175-
output.putString("application");
176-
Serializer.serialize(output, application);
177-
}
178-
if (additional != null) {
179-
// Add additional parameters
180-
for (Map.Entry<String, Object> entry : additional.entrySet()) {
181-
output.putString(entry.getKey());
182-
Serializer.serialize(output, entry.getValue());
183-
}
184-
}
154+
/** {@inheritDoc} */
155+
@Override
156+
public String toString() {
157+
return String.format("Status code: %s level: %s description: %s", code, level, description);
185158
}
186159

187160
@SuppressWarnings("unchecked")
188-
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
189-
code = (String) in.readObject();
190-
description = (String) in.readObject();
191-
level = (String) in.readObject();
192-
additional = (Map<String, Object>) in.readObject();
161+
@Override
162+
public void readExternal(IDataInput in) {
163+
code = (String) in.readUTF();
164+
description = (String) in.readUTF();
165+
level = (String) in.readUTF();
193166
application = in.readObject();
167+
additional = (Map<String, Object>) in.readObject();
194168
}
195169

196-
public void writeExternal(ObjectOutput out) throws IOException {
197-
out.writeObject(code);
198-
out.writeObject(description);
199-
out.writeObject(level);
170+
@Override
171+
public void writeExternal(IDataOutput out) {
172+
out.writeUTF(code);
173+
out.writeUTF(description);
174+
out.writeUTF(level);
200175
if (application != null) {
201-
out.writeObject(additional);
176+
out.writeObject(application);
177+
} else {
178+
out.writeObject(null);
202179
}
203180
if (additional != null) {
204-
out.writeObject(application);
181+
out.writeObject(additional);
182+
} else {
183+
out.writeObject(null);
205184
}
206185
}
186+
207187
}

common/src/main/java/org/red5/server/net/rtmp/status/StatusObjectService.java

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,15 @@ public class StatusObjectService implements StatusCodes, InitializingBean {
4646
* Initialization
4747
*/
4848
public void afterPropertiesSet() throws Exception {
49-
log.trace("Loading status objects");
50-
loadStatusObjects();
51-
log.trace("Caching status objects");
52-
cacheStatusObjects();
49+
log.trace("Loading and caching status objects");
50+
loadAndCacheStatusObjects();
5351
log.debug("Status service ready");
5452
}
5553

5654
/**
57-
* Creates all status objects and adds them to status objects map
55+
* Creates all status objects and adds them to status objects map; then caches them.
5856
*/
59-
public void loadStatusObjects() {
57+
public void loadAndCacheStatusObjects() {
6058
statusObjects = new HashMap<>();
6159

6260
statusObjects.put(NC_CALL_FAILED, new StatusObject(NC_CALL_FAILED, StatusObject.ERROR, ""));
@@ -103,31 +101,23 @@ public void loadStatusObjects() {
103101
statusObjects.put(NS_PLAY_FILE_STRUCTURE_INVALID, new StatusObject(NS_PLAY_FILE_STRUCTURE_INVALID, StatusObject.ERROR, ""));
104102
statusObjects.put(NS_PLAY_NO_SUPPORTED_TRACK_FOUND, new StatusObject(NS_PLAY_NO_SUPPORTED_TRACK_FOUND, StatusObject.ERROR, ""));
105103

106-
}
107-
108-
/**
109-
* Cache status objects
110-
*/
111-
public void cacheStatusObjects() {
112-
113-
cachedStatusObjects = new HashMap<String, byte[]>();
114-
104+
cachedStatusObjects = new HashMap<>();
115105
String statusCode;
116106
IoBuffer out = IoBuffer.allocate(256);
117107
out.setAutoExpand(true);
118-
119108
for (String s : statusObjects.keySet()) {
120109
statusCode = s;
121110
StatusObject statusObject = statusObjects.get(statusCode);
122-
if (statusObject instanceof RuntimeStatusObject) {
111+
if (RuntimeStatusObject.class.isAssignableFrom(statusObject.getClass())) {
112+
log.debug("Skip caching runtime status object: {}", statusCode);
123113
continue;
124114
}
125115
serializeStatusObject(out, statusObject);
126116
out.flip();
127117
if (log.isTraceEnabled()) {
128118
log.trace(HexDump.formatHexDump(out.getHexDump()));
129119
}
130-
byte[] cachedBytes = new byte[out.limit()];
120+
byte[] cachedBytes = new byte[out.remaining()];
131121
out.get(cachedBytes);
132122
out.clear();
133123
cachedStatusObjects.put(statusCode, cachedBytes);

common/src/main/java/org/red5/server/service/Call.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@
77

88
package org.red5.server.service;
99

10-
import java.io.Externalizable;
11-
import java.io.IOException;
12-
import java.io.ObjectInput;
13-
import java.io.ObjectOutput;
14-
10+
import org.red5.io.amf3.IDataInput;
11+
import org.red5.io.amf3.IDataOutput;
12+
import org.red5.io.amf3.IExternalizable;
1513
import org.red5.server.api.service.IServiceCall;
14+
import org.slf4j.Logger;
15+
import org.slf4j.LoggerFactory;
1616

1717
/**
1818
* Basic service call (remote call) implementation
1919
*
2020
* @author The Red5 Project
2121
* @author Luke Hubbard, Codegent Ltd ([email protected])
2222
*/
23-
public class Call implements IServiceCall, Externalizable {
23+
public class Call implements IServiceCall, IExternalizable {
2424

25-
private static final long serialVersionUID = -3699712251588013875L;
25+
private static final Logger log = LoggerFactory.getLogger(Call.class);
2626

2727
/**
2828
* Pending status constant
@@ -279,25 +279,37 @@ public String toString() {
279279
return sb.toString();
280280
}
281281

282-
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
282+
@Override
283+
public void readExternal(IDataInput in) {
283284
// keep a time of receipt
284285
readTime = System.currentTimeMillis();
285286
// read-in properties
286-
serviceName = (String) in.readObject();
287-
serviceMethodName = (String) in.readObject();
288-
arguments = (Object[]) in.readObject();
289287
status = in.readByte();
288+
serviceName = (String) in.readUTF();
289+
serviceMethodName = (String) in.readUTF();
290+
arguments = (Object[]) in.readObject();
291+
if (log.isDebugEnabled()) {
292+
for (int i = 0; i < arguments.length; i++) {
293+
log.debug("ReadExt - Arg: {} type: {} => {}", i, (arguments[i] != null ? arguments[i].getClass().getName() : null), arguments[i]);
294+
}
295+
}
290296
exception = (Exception) in.readObject();
291297
}
292298

293-
public void writeExternal(ObjectOutput out) throws IOException {
299+
@Override
300+
public void writeExternal(IDataOutput out) {
294301
// keep a time of receipt
295302
writeTime = System.currentTimeMillis();
296303
// write-out properties
297-
out.writeObject(serviceName);
298-
out.writeObject(serviceMethodName);
299-
out.writeObject(arguments);
300304
out.writeByte(status);
305+
out.writeUTF(serviceName);
306+
out.writeUTF(serviceMethodName);
307+
if (log.isDebugEnabled()) {
308+
for (int i = 0; i < arguments.length; i++) {
309+
log.debug("WriteExt - Arg: {} type: {} => {}", i, (arguments[i] != null ? arguments[i].getClass().getName() : null), arguments[i]);
310+
}
311+
}
312+
out.writeObject(arguments);
301313
out.writeObject(exception);
302314
}
303315
}

0 commit comments

Comments
 (0)