I am currently working on a wall mounted touch wiz for Android. Therefore i added a new websocket method: rest/items
to register for changes to all items. I would appreciate if somebody can test it or use it.
I will add that this was merged a few minutes ago and will be on cloudbees soon. If you currently use the endpoint /rest/items in your application it would be great to get feedback that this continues to work as expected (without web sockets).
@querdenker2k:
Could you please update the wiki with what you changed so I can read up on it?
That would be very nice.
Thanks for reminder. Adding description to āServer-Pushā Section.
Hey Guys. This is confusing. The wiki still says āwebsocket server-push does not work for /rest/itemsā (āYou do not get notifications from all items, item groups, or item states.ā) On the other hand, the PR says it should work:
So does this thread, if I got this right. Iām currently running OpenHAB 1.8 from the .deb repo, and it does not seem to work. Is there an error on my side or is this just not implemented yet, even though the PR and this thread say so?
Perhaps you can clear up my confusion a bit here, thanks.
I added the PR and for me its working. I havenāt updated to 1.8, but the feature is still in the code so it should work.
This is some code which works for 1.7.1.
final String stateUrl = restUrl + ITEMS;
LOG.debug("creating websocket");
final AtmosphereClient client = ClientFactory.getDefault().newClient(AtmosphereClient.class);
final AtmosphereRequest request = client.newRequestBuilder()
.uri(stateUrl)
.header("Accept", MediaType.APPLICATION_JSON)
.header("type", "json")
.queryString("type", "json")
.transport(Request.TRANSPORT.WEBSOCKET)
.transport(Request.TRANSPORT.STREAMING)
.transport(Request.TRANSPORT.LONG_POLLING)
.build();
final Realm.RealmBuilder realmBuilder = new Realm.RealmBuilder();
if (this.username != null && this.password != null) {
realmBuilder.setPrincipal(this.username)
.setPassword(this.password)
.setUsePreemptiveAuth(true)
.setScheme(Realm.AuthScheme.BASIC);
}
final AsyncHttpClientConfig httpClientConfig = new AsyncHttpClientConfig.Builder()
.setRealm(realmBuilder.build())
.build();
final DefaultOptions options = client.newOptionsBuilder()
.runtime(new AsyncHttpClient(httpClientConfig))
.reconnect(false)
.requestTimeoutInSeconds(Integer.MAX_VALUE)
.build();
This is also not working for me. Iām trying from the atmosphere javascript library, using this code:
`
var socket = $.atmosphere;
var request = {
url: "http://localhost:8080/rest/items?type=json",
contentType: "application/json",
header: {"Accept": "application/json"},
trackMessageLength: true,
shared: true,
transport: 'websocket',
fallbackTransport: 'long-polling'
};
request.onOpen = function () {
console.info("opOpen");
};
request.onMessage = function (message) {
console.info("onMessage", message);
console.info(JSON.parse(message.responseBody));
};
var subSocket = socket.subscribe(request);
`
onMessage is never called, but if I switch the url to sitemaps, then I get results. Iām using the demo sitemaps and items. Iām using 1.8
Ok, i will update my server to 1.8 and test again with this version.
Thanks. If it helps, Iāve just taken the 1.8 core, applied the demo for 1.8, and used this code (using jquery atmosphere).
As an interesting side note, I noticed that when I subscribe to /rest/sitemaps and set type=json, it returned sitemap is chunked into a number of onMessage calls. This is due to the default max message size of atmosphere being 8kB. The problem is that you arenāt aware when the message has finished so you canāt reliably concat the messages together. Iāll probably increase the default max size, but something to keep in mind.
Iāve tested with 1.8 core and it still works fine.
Ok, I finally got this to work, using this code:
var socket = $.atmosphere;
var request = new $.atmosphere.AtmosphereRequest();
request.url = "http://localhost:8080/rest/items?type=json";
request.contentType = "application/json";
request.headers = {"Accept": "application/json", "type": "json"};
request.transport = 'websocket';
request.fallbackTransport = 'long-polling';
request.onOpen = function () {
console.info("opOpen");
};
request.onMessage = function (message) {
console.info("onMessage", message);
console.info(message.responseBody);
};
var subSocket = socket.subscribe(request);
Iām not entirely sure why the other code i posted doesnāt work. The other thing that threw me was I was expecting the initial subscription to return the current state of all items, not for it to just send through updates after the subscription. I think it would be nice for the first subscription request to return the current state of all items, so that I donāt have to make a separate REST request to items. Iām sure that would prevent race conditions as well. Perhaps it should be an option on the query string, if thatās possible.
Hi Marc,
I would like to use server side push for a html page displaying some items and trying to reuse your code. unfortunately I am receiving an error:
TypeError: undefined is not an object (evaluating ānew $.atmosphere.AtmosphereRequestā)
Any idea?
this my test html
<html>
<header><title>This is title</title></header>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
var socket = $.atmosphere;
var request = new $.atmosphere.AtmosphereRequest();
request.url = "http://localhost:8080/rest/items?type=json";
request.contentType = "application/json";
request.headers = {"Accept": "application/json", "type": "json"};
request.transport = 'websocket';
request.fallbackTransport = 'long-polling';
request.onOpen = function () {
console.info("opOpen");
};
request.onMessage = function (message) {
console.info("onMessage", message);
console.info(message.responseBody);
};
var subSocket = socket.subscribe(request);
</script>
Hello world
</body>
</html>