How to deal with information received in two packets - actionscript-3

This is the case. I want to make a game, client being made in flash and server on java. From server side, the first byte i write on the stream is the protocol id, like this:
try
{
Output.writeByte(LOGIN);
Output.writeByte((byte)ID);
Output.writeByte(new_position.x);
Output.writeByte(new_position.y);
Output.flush();
}
After the 'onResponse' event is triggered, the socket is read like this:
type:int = socket_client.readByte();
if (type == 0x1)
FP.console.log("You are logged as " + socket_client.readByte() + " in x:" + socket_client.readByte() + " y:" + socket_client.readByte() );
else if (type == 0x2)
FP.console.log("You are now in x:" + socket_client.readByte() + " y:" + socket_client.readByte());
As you probably have guessed by now, this gives me some problems. Sometimes, server sends the information split in two, so the above code throws an EOF exception. Tracing the following code gives me sometimes this result:
trace("SIZE: " + socket_client.bytesAvailable);
//var type:int = socket_client.readByte();
var values:String = "";
while (socket_client.bytesAvailable > 0)
values += socket_client.readByte() + " ";
trace(values);`
Values:
SIZE: 1
2
SIZE: 2
2 6
The first '2' is the protocol id, the second and the third stands for x and y values.
Now, the question is, how can i prevent this to happen? How could i 'wait' until i have all the information needed?
Btw, on java this never happens, but i have no more control than on as3.

Add BufferedOutputStream in output initialization like this:
Output = new DataOutputStream(new BufferedOutputStream(connection.getOutputStream()));

Basically you need to switch your message format from [type, data] to [type, length, data]. Then, wait to process the data until bytesAvailable >= length, otherwise put it into a buffer.
Here is an example SOCKET_DATA handler that uses this logic:
https://github.com/magicalhobo/Flash-CS5-mobile-proxy/blob/master/com/magicalhobo/mobile/proxy/MobileClient.as#L110

Related

Intermittently: Couchbase Save Not Happening

I am using Couchbase java sdk client 2.7.11 with Couchbase 6.0 community addition. While performing upsert it gives me success response, but when I fetch the document or see through Couchbase UI, it’s not available.
//getClient returning me "api com.couchbase.client.java.Bucket" instance
private static final RetryWhenFunction RETRY_POLICY =
RetryBuilder.anyOf( TimeoutException.class,
TemporaryFailureException.class,
RequestCancelledException.class,
BackpressureException.class,
CASMismatchException.class)
.delay(Delay.exponential(TimeUnit.MILLISECONDS, 50))
.max(3)
.build();
int expiryTime = Instant.now().getEpochSecond() + (10 * 60);
StringDocument document = StringDocument.create("ABC_Test",expiryTime , "SomeValue");
StringDocument savedDocument = getClient().async().upsert(document).retryWhen(RETRY_POLICY)
.doOnError(exception -> {
String msg = "Unable to update a document = " + exception.getMessage();
LOGGER.error(()->msg);
})
.doOnCompleted(() -> LOGGER.debug(()-> "Succesfully saved document with key \"" + key))
.doAfterTerminate(() -> LOGGER.debug(()-> "Processing save document with key \"" + key + "\" Completed."))
.toBlocking()
.singleOrDefault(null);
if(savedDocument==null) {
LOGGER.error(()-> "Document with id couldn't be saved: " + key);
} else {
LOGGER.debug(()-> "Saved document: \n" + savedDocument);
}
I faced the similar issue when trying to use QueuePush. The Queue push gave me the success response but Queue pop says queue itself doesn’t exist. I intend to use both of the saving within next 5 sec for say. I do not have any load test running that could indicate towards Async delay behavior.
//expirationTime is quiet ahead in future.
getClient().async()
.queuePush(queueName, queueElement, MutationOptionBuilder.builder().createDocument(true).expiry(expirationTime))
.retryWhen(RETRY_POLICY)
.doOnError(exception -> LOGGER.error(() -> “Unable to add element '”+ queueElement +"’ in queue ‘" + queueName +
"’ Exception = " + exception.getMessage()))
.doOnCompleted(() -> LOGGER.debug(()-> "Succesfully saved document in queue “” + queueName))
.doAfterTerminate(latch::countDown).subscribe();
Both of above scenario have been noticed intermittently. Could you please suggest to diagnose this one? Does Community Version has a way to enable Document Level Auditing?
I have posted the similar question on Couchbase forum too, trying to bring it for bigger audience https://forums.couchbase.com/t/intermittently-couchbase-save-not-happening/28006 and get the right direction.
Thank you in advance.
Regards

OpenWeatherMap JSON API forecast for rain and snow

I am facing problems forcing my code run smoothly when there is no value for Parameters rain and snow. Actually it loops as long as there are values for these parameters and if not it ends.
I have included gson library for helping me get the values as JSON objects/strings/double etc.
for (int l=0; l<40; l++) {
Forecast fcath = new Forecast();
fcath.setMain_temp(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("main").getAsJsonObject().get("temp").getAsDouble());
fcath.setWeather_description(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("weather").getAsJsonArray().get(0).getAsJsonObject().get("description").getAsString());
fcath.setClouds_all(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("clouds").getAsJsonObject().get("all").getAsInt());
fcath.setWind_speed(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("wind").getAsJsonObject().get("speed").getAsDouble());
fcath.setDt_txt(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("dt_txt").getAsString());
fcath.setRain(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("rain").getAsJsonObject().get("3h").getAsDouble());
fcath.setSnow(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("snow").getAsJsonObject().get("3h").getAsDouble());
f.add(fcath);
System.out.println("Date: " + f.get(l).getDt_txt() + " Temp: " + f.get(l).getMain_temp() + " Celsius " + " Chance of Rain: " + f.get(l).getRain() + " Chance of Snow: " + f.get(l).getSnow());
}
Without fcath.setRain and fcath.setSnow code lines the output is the following:
Working output photo
Assuming that there is no rain chance in the forecast
e.g.
fcath.setRain(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("rain").getAsJsonObject().get("3h").getAsDouble()); == {}
it gives me NullPointerException
NullPointerException photo
Is still hard to say with the information provided, but seems that if the is no rain chance, then probably
obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("rain").getAsJsonObject()
is null. Then you cannot do a get("3h").getAsDouble() from a null object.

Will Javascript read returned string as script or treat it as a string?

I am wondering is it possible to run a function that outputs a line that javascript can read and recognize as a variable and not as a string? I have pulled JSON data and what I want to do is to take the object data and dynamically write out variables from it on the fly. I hope this is possible..
function createVar(data){
return "var_" + data.name + data.id + "=_" + data.desc;
//This will return the line :
var itemModel1 = "I no longer vote";
}
I have to say that I don't really recommend this, but it does work.
function createVar(data){
return "var " + data.name + data.id + "='" + data.desc + "'";
}
var exampleData = {name:"itemModel", id:"1", desc:"Today we went to the mall"}
eval(createVar(exampleData));
console.log(itemModel1); //outputs "Today we went to the mall" to the console
I will clarify by saying that if you actually need to generate variable names on the fly, this will do the trick. But I would more closely examine your code to see if there is another way to accomplish what you are trying to do. As always, you have to be very careful with eval, bad things can happen if user input gets passed as your data parameter.

Eliminating repeated code (DRY principle) in this chain of responsibility caching function

I am creating a Map Tile Server class, with a function get_tile(tilekey) which should do the following:
Try to retrieve the image from an in-memory dictionary (faster);
If not present, try to retrieve the image from disk;
If not present, try to download the image form the internet;
But, since I might call the same image soon after, I must also fill the faster cache layers when I have to use a slower one, and this is generating repeated code. Below is a Python-syntax-style pseudocode of what is working now:
## WARNING: this is Pseudo-Code!!
def get_tile(tilekey):
if tilekey in tiles.keys():
tileimage = tiles[tilekey]
elif file.exists (tilekey + ".jpg"):
tiles[tilekey] = open_image_from_disk(tilekey + ".jpg")
tileimage = tiles[tilekey]
else:
download_image_to_disk(urltemplate + tilekey + ".jpg")
tiles[tilekey] = open_image_from_disk(tilekey + ".jpg")
tileimage = tiles[tilekey]
return tileimage
I have this sort of "try to do f1; if not, do f2, f1; if not, do f3, f2, f1", and if this was deeper, then the amount of repeated code would grow geometrically.
I have the impression that some clever combination of some tricks like try/except/finally or recursion/delegation, or some other clever control flow construct might make things cleaner.
As a final note, I plan to implement this in more than one language (Python and C# at least), so it's more of a design-pattern question than a problem-specific, language-dependent question.
How about this:
## WARNING: this is Pseudo-Code!!
def get_tile(tilekey):
if !tilekey in tiles.keys():
if !file.exists (tilekey + ".jpg"):
download_image_to_disk(urltemplate + tilekey + ".jpg")
tiles[tilekey] = open_image_from_disk(tilekey + ".jpg")
return tiles[tilekey]

"CalendarApp: Mismatch: etags" when adding reminders - Google Apps Scripts

I have a small Google Apps Script that processes a date column in a spreadsheet and generates entries in a Calendar (birthdays).
Work is fine, but when adding reminders to the (recently-created) CalendarEvent, an error is thrown :
Service error: CalendarApp: Mismatch: etags = ["GUQKRgBAfip7JGA6WhJb"], version = [63489901413]
I've tried to perform 1 second sleep after creating event (wait for changes to be done in calendar), but no luck on this...
BTW, events are created succesfully, only reminders cannot be added.
PD: the calendar is one I own, but not my primary calendar.
Here is part of the code:
try
{
birthday = new Date(Data[i][BirthColumn]);
birthday.setFullYear(today.getFullYear());
birthday.setUTCHours(12);
birthlist += Data[i][NameColumn] + " --> " + birthday + "\n";
calendarevent = cal.createAllDayEventSeries("¡Cumpleaños " + Data[i][NameColumn] + "!", birthday, CalendarApp.newRecurrence().addYearlyRule().times(YearsInAdvance));
if (calendarevent == null)
success = false;
else
{
//This sentence fails every single time.
calendarevent.addEmailReminder(0);
calendarevent.addPopupReminder(0);
calendarevent.addSmsReminder(0);
}
}
catch (ee)
{
var row = i + 1;
success = false;
errlist += "Error on row " + row + ": check name and birth date. Exception Error: " + ee.message + "\n";
}
This is the portion of the code I finally change to make it work, as Serge insas suggest me before:
if (calendarevent == null)
success = false;
else
{
cal.getEventSeriesById(calendarevent.getId()).addEmailReminder(0);
cal.getEventSeriesById(calendarevent.getId()).addPopupReminder(0);
cal.getEventSeriesById(calendarevent.getId()).addSmsReminder(0);
}
This is a known issue
See comment nr 67 for a working workaround : the trick is to re-call the event for every item you want to add (reminder, popup...) using cal.getEventSeriesById(eventID) after you get the Id simply with .getId()
I use it in some scripts and it solved the issue for me.