所以我一直在尝试使用Play Framework 1.3实现正确的EventStream解决方案,但是我无法让它正常工作。一个例外不断被抛出,但我不确定原因是什么。
任何人都可以提供示例实现或指向我吗?
这是我控制器中的方法。
public static void stream() {
response.contentType = "text/event-stream";
response.encoding = "UTF-8";
response.status = 200;
response.chunked = true;
// a record of the last ID that this request... requested
Long lastId = 0L;
// since this request has only been initiated, the first thing to do is return a list of whats in the queue
List<F.IndexedEvent> archive = StreamQueue.getRecentNotifications(lastId);
if (!archive.isEmpty()) {
// write that list out in the response
response.writeChunk(//a string representing the entire list as a single event);
// update out internal reference to the lastId
lastId = archive.get(archive.size() - 1).id;
}
// keep this connection alive
while (true) {
// await the promise of more notifications for the stream
List<F.IndexedEvent<StreamQueue.Notification>> notifications = await(StreamQueue.getNextNotification(lastId));
// for each notification, write it out as a separate event
for (int i = 0; i < notifications.size(); i++) {
response.writeChunk(//a string representing a single event using notifications.get(i));
// update out internal reference to the lastId
lastId = notifications.get(i).id;
}
}
}
这是我对队列StreamQueue.java的实现:
public class StreamQueue {
final ArchivedEventStream<StreamQueue.Notification> notifications = new ArchivedEventStream<StreamQueue.Notification>(100);
static StreamQueue instance = null;
public static StreamQueue get() {
if(instance == null) {
instance = new StreamQueue();
}
return instance;
}
// the method to call when I want to send an event
public static void alert(Notification.Type type, Object... args){
get().addMessage((String) args[0]);
}
public static F.Promise<java.util.List<F.IndexedEvent<Notification>>> getNextNotification(Long lastId) {
return get().getNotificationsStream().nextEvents(lastId);
}
public static java.util.List<F.IndexedEvent> getRecentNotifications(Long lastId) {
return get().getNotificationsStream().availableEvents(lastId);
}
public ArchivedEventStream<StreamQueue.Notification> getNotificationsStream() {
return notifications;
}
private void addMessage(String message){
notifications.publish(new StreamQueue.MessageEvent(message));
}
public static abstract class Notification extends F.IndexedEvent {
public enum Type {
ISSUE,
MESSAGE;
}
final public Type type;
final public Long timestamp;
public Notification(Type type) {
super(type);
this.type = type;
this.timestamp = System.currentTimeMillis();
}
public Long getId() {
return this.id;
}
public String toJson() {
return new JSONSerializer().exclude("class").serialize(this);
}
}
public static class MessageEvent extends StreamQueue.Notification {
public final String message;
public MessageEvent(String message) {
super(Type.MESSAGE);
this.message = message;
}
public String toJson() {
return new JSONSerializer().include("message").exclude("*").serialize(this);
}
}
}
最后,我得到了例外:
Internal Server Error (500) for request GET /stream
Execution exception
InvocationTargetException occured : null
play.exceptions.JavaExecutionException
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:230)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.reflect.InvocationTargetException
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:524)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:475)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:451)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:446)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:160)
... 1 more
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map
at controllers.StreamController.stream(StreamController.java)
... 6 more
我ArchivedEventStream.nextEvents(...)
呼叫的StreamQueue.getNextNotification(...)
似乎引发了异常。原因似乎是Long
被投射到Map
,但我决不尝试这样做。
提前感谢您的帮助!
更新 所以我在Play 1.2.5中尝试了我的项目,并且流媒体工作完美。但是,该项目要求我们使用Play 1.3。
答案 0 :(得分:0)
原因位于堆栈跟踪的底部:
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map
我认为您正在尝试将Notification.timestamp
投射到地图StreamController
。