CN1 Socket cannot send >7200 bytes - codenameone

Having trouble sending a large number of bytes from CN1 client to Server. Code below works for anything less than ~7200 bytes. However at byte 7240 the bytes received by the server becomes all zeroes. Not sure why this is occurring, as the connection is still live. The server can still push bytes back just unsure why the client cannot send more data than ~7200. Any advice would be greatly appreciated. Thanks!
if (!outgoingMessages.isEmpty()) {
Socket.connect("my.server.net", 1234, new SocketConnection() {
#Override
public void connectionEstablished(InputStream inStream, OutputStream outStream) {
try {
byte[] msgBytes = outgoingMessages.pop();
outStream.write(ByteConvertor.intToBytes(msgBytes.length));
outStream.write(msgBytes);
} catch(Exception err) {
err.printStackTrace();
}
}
#Override
public void connectionError(int errorCode, String message) {
System.out.println("Error");
}
});
}
Clarification: This is specific to com.codename1.io.Socket and not Steve's CN1Sockets lib

I think this might have been fixed by this pull request, its not available in the simulator builds yet but should work in the source/device. We should update the plugin this week at some point so code should hopefully "just work".

Related

Can async subscriber example lose messages?

Starting off with pubsub. When reading the google cloud documentation, i ran into a snippet of code, and i think i see a flaw with the example.
This is the code i am talking about. It uses the async subscriber.
public class SubscriberExample {
private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId();
private static final BlockingQueue<PubsubMessage> messages = new LinkedBlockingDeque<>();
static class MessageReceiverExample implements MessageReceiver {
#Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
messages.offer(message);
consumer.ack();
}
}
public static void main(String... args) throws Exception {
String subscriptionId = args[0];
ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(
PROJECT_ID, subscriptionId);
Subscriber subscriber = null;
try {
subscriber =
Subscriber.newBuilder(subscriptionName, new MessageReceiverExample()).build();
subscriber.startAsync().awaitRunning();
while (true) {
PubsubMessage message = messages.take();
processMessage(message);
}
} finally {
if (subscriber != null) {
subscriber.stopAsync();
}
}
}
My question is, what if a bunch of messages have been acknowledged, and the BlockingQueue is not empty, and the server crashes. Then i would lose some messages right? (Acknowledged in PubSub, but not actually processed).
Wouldn't the best implementation be to only acknowledge the message after the it has been processed? Instead of acknowledging it and leaving it on a queue, and assuming it will be processed. I understand this will decouple the receiving of messages and process of messages, and potentially increase throughput, but still it risks losing messages right?
Yes, one should not acknowledge a message until it has been fully processed. Otherwise, the message may never be processed because it will not be redelivered in the event of a crash or restart if it was acknowledged. I have entered an issue to update the example.

use timeWindow and processingTime but data Ingestion was blockd

When I use Windows All, because there is only one degree of parallelism, there is a bottleneck in processing. Therefore, I change to timeWindow and use processTime, but I encounter a new problem, data can not be ingested. From the log on the console, it can be seen that only more than ten data are processed every second, if I use Windows All. It can process tens of thousands of data per second. So I don't know why.
When I added waterMark to time Windows, I found that time Windows can handle a large number of data per second, but upstream data still accumulates
SingleOutputStreamOperator<DataSetPOJO> dataSetPOJOSingleOutputStreamOperator = sdkInfos.flatMap(...);
dataSetPOJOSingleOutputStreamOperator.keyBy(new KeySelector<DataSetPOJO, String>() {
#Override
public String getKey(DataSetPOJO dataSet) {
return dataSet.getPartitionKey();
}
}).timeWindow(Time.seconds(3))
.process(new ProcessWindowFunction<DataSetPOJO, List<DataSetPOJO>, String, TimeWindow>() {
#Override
public void process(String key, Context context, Iterable<DataSetPOJO> elements,
Collector<List<DataSetPOJO>> out) throws Exception {
ArrayList<DataSetPOJO> dataSetPOJO = Lists.newArrayList(elements);
if (dataSetPOJO.size() > 0) {
// log.info("key~~~~~~~~~~~~~~:" + key);
// log.info("dataSetPOJO.size():" + dataSetPOJO.size());
out.collect(dataSetPOJO);
}
}
}).addSink(new Sink2Postgre());
I hope I can save enough batches in windows to write PostgreSQL,If this is not correct, how to write, if it is no problem, what will be the problem. Fink Version 1.5.3

How to get the complete code for braintree in codename one

Pls is the code below is enough to handle braintree for payment?
Purchase.startOrder(new Purchase.Callback() {
public String fetchToken() {
return "";
}
public void onPurchaseSuccess(String nonce) {
}
public void onPurchaseFail(String errorMessage) {
}
public void onPurchaseCancel() {
}
});
For the sample test I return the token provided in braintree websites like this
Purchase.startOrder(new Purchase.Callback() {
public String fetchToken() {
return "eyJ2ZXJzaW9uIjoyLCJhdXRob3JpemF0aW9uRmluZ2VycHJpbnQiOiI0ZDFkOWFkOGFhZDFlZDhiZjA4MDMwZGRmNWM0ZWEwZjc0ZDYwY2I4Zjg5MDNkYzVmYTUyNTM1MzhkMWIwYjNkfGNyZWF0ZWRfYXQ9MjAxNy0wNS0yMVQwNzo0MjoxNS4xODgzNDQ0MjIrMDAwMFx1MDAyNm1lcmNoYW50X2lkPTM0OHBrOWNnZjNiZ3l3MmJcdTAwMjZwdWJsaWNfa2V5PTJuMjQ3ZHY4OWJxOXZtcHIiLCJjb25maWdVcmwiOiJodHRwczovL2FwaS5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tOjQ0My9tZXJjaGFudHMvMzQ4cGs5Y2dmM2JneXcyYi9jbGllbnRfYXBpL3YxL2NvbmZpZ3VyYXRpb24iLCJjaGFsbGVuZ2VzIjpbXSwiZW52aXJvbm1lbnQiOiJzYW5kYm94IiwiY2xpZW50QXBpVXJsIjoiaHR0cHM6Ly9hcGkuc2FuZGJveC5icmFpbnRyZWVnYXRld2F5LmNvbTo0NDMvbWVyY2hhbnRzLzM0OHBrOWNnZjNiZ3l3MmIvY2xpZW50X2FwaSIsImFzc2V0c1VybCI6Imh0dHBzOi8vYXNzZXRzLmJyYWludHJlZWdhdGV3YXkuY29tIiwiYXV0aFVybCI6Imh0dHBzOi8vYXV0aC52ZW5tby5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tIiwiYW5hbHl0aWNzIjp7InVybCI6Imh0dHBzOi8vY2xpZW50LWFuYWx5dGljcy5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tLzM0OHBrOWNnZjNiZ3l3MmIifSwidGhyZWVEU2VjdXJlRW5hYmxlZCI6dHJ1ZSwicGF5cGFsRW5hYmxlZCI6dHJ1ZSwicGF5cGFsIjp7ImRpc3BsYXlOYW1lIjoiQWNtZSBXaWRnZXRzLCBMdGQuIChTYW5kYm94KSIsImNsaWVudElkIjpudWxsLCJwcml2YWN5VXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL3BwIiwidXNlckFncmVlbWVudFVybCI6Imh0dHA6Ly9leGFtcGxlLmNvbS90b3MiLCJiYXNlVXJsIjoiaHR0cHM6Ly9hc3NldHMuYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhc3NldHNVcmwiOiJodHRwczovL2NoZWNrb3V0LnBheXBhbC5jb20iLCJkaXJlY3RCYXNlVXJsIjpudWxsLCJhbGxvd0h0dHAiOnRydWUsImVudmlyb25tZW50Tm9OZXR3b3JrIjp0cnVlLCJlbnZpcm9ubWVudCI6Im9mZmxpbmUiLCJ1bnZldHRlZE1lcmNoYW50IjpmYWxzZSwiYnJhaW50cmVlQ2xpZW50SWQiOiJtYXN0ZXJjbGllbnQzIiwiYmlsbGluZ0FncmVlbWVudHNFbmFibGVkIjp0cnVlLCJtZXJjaGFudEFjY291bnRJZCI6ImFjbWV3aWRnZXRzbHRkc2FuZGJveCIsImN1cnJlbmN5SXNvQ29kZSI6IlVTRCJ9LCJjb2luYmFzZUVuYWJsZWQiOmZhbHNlLCJtZXJjaGFudElkIjoiMzQ4cGs5Y2dmM2JneXcyYiIsInZlbm1vIjoib2ZmIn0=";
}
public void onPurchaseSuccess(String nonce) {
}
public void onPurchaseFail(String errorMessage) {
}
public void onPurchaseCancel() {
}
});
When I buit and install on my phone to test it out. It displays the payment method which include paypal and add debit or credit card.
When I want to integrate my own:
The problem am facing now is that at the server side, I have a code that provides client token
My questions:
1. How do I call this token in codename one, although I have code that says return "";. What am I going to return here? I pointed the url that generated the token inside the return. It didn't work.
2. If I get my own token is that enough to handle the payment? according to the code provided above.
3. Is ssl required on the server side I want to use?
Thanks for your response.
As explained in the post you need to have a server to implement payments. Instructions of implementing the server are in the braintree website which is linked too.
Just look in the server section there and implement that. You then need to return the token generated in the server to your client code.

On WP8.1 ONLY: cannot read more than 65536 bytes off an HTTP Stream

Hope someone could please provide any help on an issue I'm struggling for quite a lot of time.
Goal: I need to read an http stream from a specified URI, that I startup & endlessly read with the following code (which I stripped down to minimum so to really focus on the bare communication problem):
public void StartupStream(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
// Start the asynchronous request
request.BeginGetResponse(OnGetResponse, request);
}
private void OnGetResponse(IAsyncResult asyncResult)
{
// get the response
HttpWebRequest req = (HttpWebRequest)asyncResult.AsyncState;
try
{
using (HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(asyncResult))
{
using (Stream s = resp.GetResponseStream())
{
// dummy-read the stream forever
int readBytes = 0;
byte[] buffer = new byte[4096];
while (true)
{
readBytes += s.Read(buffer, 0, buffer.Length);
}
}
}
}
catch (Exception ex)
{
throw;
}
finally
{
req.Abort();
}
}
Issue: it happens that the above same exact code perfectly runs on a demo desktop WPF app, reading "gigabytes" of data without any issue, whereas on a Windows Phone 8.1 Store App I can only read up to 65536 bytes, and then the subsequent call to s.Read(buffer, 0, buffer.Length) (in the infinite while loop) just hangs forever, without any exception!
Things I have already tried, without any result:
Changing several values for the buffer size (i.e. 256, 512, 1024… and
so on)
Running the WP 8.1 app on both device and emulator
Sniffing traffic with WireShark, I can see the startup request is exactly the same on both WPF and WP 8.1 scenarios, and both are HTTP
1.1, and in all cases, the server (a D-link DCS-920 webcam) continues to flawlessly “pump” HTTP 1.1 responses (mjpeg data) into the stream
Does anybody have an idea of what could be going on with this bare, simple HTTP Stream usage on WP 8.1? How could there be a 65536-byte limitation on reads?
Thanks for any help!
This is how I am downloading an images from the web. The file size in the example is 1131683
string URL = "http://img.uuhy.com/uploads/2010/05/4423_Free-high-resolution-desktop-wallpaper-8.jpg";
var httpClient = new HttpClient();
var httpResponse = await httpClient.GetAsync(URL);
var ImageArray = await httpResponse.Content.ReadAsByteArrayAsync();

GAE Channel Sending First Message Repetatively

So this was working on this project a few months ago. I'm using Google App Engine's Channel API to push messages to my GWT app. I'm using http://code.google.com/p/gwt-gae-channel/ to interact through GWT.
Lets say I send 1 message to the client: "First Message"
The client will receive the message, "First Message" just fine.
Then let's say I send another message, "Second Message" to the client.
The client will again receive the message, "First Message".
This will continue happening. There have been some instances where I'll receive the second message, and it will be the message that gets stuck repeating.
When I finally close the page, and thus close the channel, I again receive the repeated message without sending something from the server.
Does anyone have any idea what is going on? I don't think this was happening when I was working on this a few months ago, and I can see no changes to the GAE Channel API.
Here is some code:
String json = AutoBeanHelper.toJson(proxy);
log.fine("Item's JSON Received: " + json);
List<ChannelEntity> channels = channelDAO.getByUserId();
if (channels.size() > 1) {
log.warning("Multiple channels for single user detected.");
}
ChannelService channelService = ChannelServiceFactory.getChannelService();
for (ChannelEntity channel : channels) {
channelService.sendMessage(new ChannelMessage(channel.getClientId(), json));
}
So whenever I store a new item of a specific type (this is in that entities update function):
1. I turn it into JSON.
2. I then log that JSON.
3. I get that users channel.
4. I send it to that users channel.
When I look at my logs, I see that the variable above that I'm logging is showing correctly, meaning I'm logging the correct JSON message but when I display the JSON in an alert on the client-side as soon as it gets to the client, it's the previous message that seems to be stuck repeating. I really don't see what I could be doing wrong here.
Let me know if you would like to see another part of the code. For good measure, here is the code on the client:
eventBus.addHandler(ReceivedChannelTokenEvent.TYPE, new ReceivedChannelTokenEventHandler() {
#Override
public void onEvent(ReceivedChannelTokenEvent event) {
ChannelFactory.createChannel(event.getChannelToken(), new ChannelCreatedCallback() {
#Override
public void onChannelCreated(Channel channel) {
final Socket channelSocket = channel.open(new SocketListener() {
#Override
public void onOpen() {
Window.alert("Channel Opened");
}
#Override
public void onMessage(String json) {
Window.alert(json);
eventBus.fireEvent(new MessageReceivedEvent(json));
}
#Override
public void onError(SocketError error) {
Window.alert("Channel Error: " + error.getDescription());
if ( error.getDescription().equals(CHANNEL_ERROR_TOKEN_TIME_OUT) ) {
eventBus.fireEvent(new ChannelTimeOutEvent());
}
}
#Override
public void onClose() {
Window.alert("Channel Closed.");
}
});
Window.addWindowClosingHandler(new Window.ClosingHandler() {
#Override
public void onWindowClosing(ClosingEvent event) {
channelSocket.close();
}
});
}
});
}
});
I see a lot of questions on SO where someone has a bug in their code but think it's part of the framework. Without seeing any code, I suspect there's some bug where you think you're sending "Second Message", but you're really sending a cached version of "First Message".
So I was finally able to figure it out. It seems that in the onMessage function within the app when I call
eventBus.fireEvent(new MessageReceivedEvent(json));
it seems that it never returns from this, thus never exiting the onMessage function in the code, causing me to receive the same message repetitively.

Resources