我是泽西岛使用SSE的新手,有以下情况。
我有一个JAXB注释类,它表示Raspberry Pi的I/O并对其起作用(类GpioSymation)。
客户端类通过返回类的XML对象表示的方法getUpdate()访问I/O的状态。
@XmlRootElement
public class GpioRepresentation implements GpioSubject
{
...
/**
* Returns an object of this class with the current
* representation of the I/O states
* @return this
*/
public synchronized GpioRepresentation getUpdate()
{
this.getGarageDoorInputState();
this.getZoneOneFeedback();
this.getZoneTwoFeedback();
this.getZoneThreeFeedback();
this.getGarageDoorRelayState();
this.getZoneOneRelayState();
this.getZoneTwoRelayState();
this.getZoneThreeRelayState();
return this;
}
...
}
使用getUpdate()的客户端是HomeResource类,方法getPiStatusStream()。这是一个JAX-RS注释方法,并提供远程客户端服务器发送的事件。目前,该方法如图所示编写,在一个单独的线程中有一个连续循环,用于轮询更新。
@Path("/homeservice")
@RolesAllowed({"ADMIN", "USER"})
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
public class HomeResource
{
private static final Logger LOGGER = LoggerFactory.getLogger(HomeResource.class);
private GpioRepresentation piService;
...
/**
* gets status information on the Raspberry Pi's
* I/O and returns it to the client on a continuous basis
* and only if it changes.
* @return EventOutput
*/
@GET
@Path("/iostatus")
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput getPiStatusStream()
{
final EventOutput eventOutput = new EventOutput();
new Thread(new Runnable()
{
public void run()
{
try {
String gdState = null;
String zOneState = null;
String zTwoState = null;
String zThreeState = null;
String gdRState = null;
String zOneRState = null;
String zTwoRState = null;
String zThreeRState = null;
String lastgdState = null;
String lastzOneState = null;
String lastzTwoState = null;
String lastzThreeState = null;
String lastgdRState = null;
String lastzOneRState = null;
String lastzTwoRState = null;
String lastzThreeRState = null;
while(true) {
final OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
final GpioRepresentation iostatus = piService.getUpdate();
gdState = piService.getGarageDoorInputState();
zOneState = piService.getZoneOneFeedback();
zTwoState = piService.getZoneTwoFeedback();
zThreeState = piService.getZoneThreeFeedback();
gdRState = piService.getGarageDoorRelayState();
zOneRState = piService.getZoneOneRelayState();
zTwoRState = piService.getZoneTwoRelayState();
zThreeRState = piService.getZoneThreeRelayState();
if (!(gdState.equals(lastgdState) && zOneState.equals(lastzOneState) && zTwoState.equals(lastzTwoState) && zThreeState.equals(lastzThreeState)
&& gdRState.equals(lastgdRState) && zOneRState.equals(lastzOneRState) && zTwoRState.equals(lastzTwoRState) && zThreeRState.equals(lastzThreeRState)))
{
OutboundEvent event = eventBuilder.data(GpioRepresentation.class, iostatus)
.mediaType(MediaType.APPLICATION_XML_TYPE)
.build();
eventOutput.write(event);
lastgdState = gdState;
lastzOneState = zOneState;
lastzTwoState = zTwoState;
lastzThreeState = zThreeState;
lastgdRState = gdRState;
lastzOneRState = zOneRState;
lastzTwoRState = zTwoRState;
lastzThreeRState = zThreeRState;
}
Thread.sleep(100);
}
}
catch (Exception exeption)
{
System.err.println("Error: " + exeption);
}
finally
{
try
{
eventOutput.close();
}
catch (IOException ioClose)
{
throw new RuntimeException("Error when closing the event output.", ioClose);
}
}
}
}).start();
return eventOutput;
}
...
}
我所看到的问题是,这不能很好地扩展。为来自远程客户端的每个GET创建线程需要时间,并且占用CPU资源。此外,我认为这不是一个优雅的解决方案。我想做的是将事件代码封装到一个单独的类中,并使用某种可以触发事件创建的观察者模式。。。。但是,如何将其绑定到资源方法中,以便将其返回到远程客户端?
有没有人能给我举一些例子,或者提供一些关于设计解决方案的建议?
解决方案是利用SSEEbroadcaster类。我让HomeService类成为GpioRepresentation类的观察者,然后调用一个新方法(broadcastIOUpdateMessage()),然后将我的事件输出到远程客户端。
public void broadcastIOUpdateMessage()
{
GpioRepresentation iostatus = piService.getUpdate();
OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
OutboundEvent event = eventBuilder.data(GpioRepresentation.class, iostatus)
.mediaType(MediaType.APPLICATION_XML_TYPE)
.build();
broadcaster.broadcast(event);
}
@GET
@Path("/iostatus")
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput getPiStatusStream()
{
final EventOutput eventOutput = new EventOutput();
this.broadcaster.add(eventOutput);
return eventOutput;
}
我正在寻找合适的资源/教程,可以帮助我开发和部署事件网格触发器,该触发器将等待图像上传到blob容器,使用python处理该图像,然后将结果保存在另一个blob容器中。我发现了许多单独的文档,它们不一定在逻辑上指导我使用Azure Portal和VSCode进行开发和部署,就像从头到尾的一步一步的演练,介绍了实现这一点的所有步骤。 任何指导将不胜感激。
当我的函数方法签名如下时,我有一个成功触发的v3 WebJob: 然而,当我添加一个输出blob时,BlobTrigger永远不会触发。 下面的文档如下:https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob#output
问题内容: 有人知道像使用jQuery的触发函数一样可以触发Prototype中的事件的方法吗? 我已经使用watch方法绑定了一个事件监听器,但是我也希望能够以编程方式触发该事件。 提前致谢 问题答案: 符合您的需求。 我已经使用了几次,它就像一个魅力。它允许您 手动触发本机事件 ,例如单击或悬停,如下所示: 这样做的好处是,所有附加的事件处理程序仍将执行,就像您自己单击该元素一样。 对于 自定
问题内容: 我正在使用哈希链接的事件将a 作为弹出窗口打开。但是 ,单击中键不会触发事件,而只会获取链接的属性值并将URL加载到新页面中。如何使用中键打开弹出窗口? 问题答案: beggs的答案是正确的,但是听起来您想阻止默认的中间点击操作。在这种情况下,请包括以下内容 preventDefault()将停止事件的默认操作。
问题内容: 我的整个项目都使用(Bluebird)Promises,但是有一个使用EventEmitter的特定库。 我想要实现以下目标: 我在Promises链中读了EventEmitter的答案。这给了我一种执行’connect’事件的回调的方法。这是我到目前为止所到之处 现在如何进一步链接“ eventB”? 问题答案: 我假设您想为每个事件做不同的事情。即使由的动作触发,您也可以将其视为另
我想自动化一个在线游戏。它在仅基于终端的情况下工作。但是我想添加一个JavaFXUI,现在我不知道把Thread放在哪里。等待直到达到某个LocalDateTime。JavaFX在哪里等待它的事件(比如按钮点击,…),我可以覆盖该方法吗?或者有没有一种方法可以为javaFX创建自定义LocalDateTime事件和侦听器? 如果在initialize()中添加一个Thread.wait,则整个场景