NServiceBus sending data question - object

i am using NServices to send an object of the class MyMusicMessage as blow:
[Serializable]
public class MyMusicMessage:IMessage
{
public Guid EventId { set; get; }
public byte[] MusicBytes { set; get; }
}
when the size of MusicBytes is about 200k, it can be sent well.
but when the size is more than 300K,there is a "MessageQueueException".
is there any limit to the object size in NServiceBus?
thanks.

One thing I noticed when transferring a (much smaller) payload as a byte array is that NServiceBus will serialize it roughly like this (from memory):
<MyByteArray>
<Byte>4</Byte>
<Byte>183</Byte>
<Byte>221</Byte>
<Byte>87</Byte>
...
<MyByteArray>
Obviously not a great way to transfer a byte array efficiently, but I'm sure the NServiceBus serializer is going for speed and efficiency, not the smallest message size possible.
While I agree that it would be best to transfer something as hefty as music data out of band, for smaller byte array payloads (like the 5-10K range) a much better alternative is to encode the byte array as a Base64 string in your message class using Convert.ToBase64String(byte[] arr) and Convert.FromBase64String(string str).

When using the XML serializer in NServiceBus (which is the default), it will serialize arrays as general purpose collections, creating an entry for each value. It is likely that that is what is causing the actual message size to be much larger than the 300KB in memory.
I suggest you switch to the Binary serializer for that message type.

MSMQ has a limit of 4M. We're working on a databus feature for 2.1 but until then I sugest that you store your music payload "out of band" and only transfer the adress where the data can be picked up in your message.
Hope this helps!

Related

How to create API key and Secure Key?

Usually if I consume third party api's, they all give us two keys and they are:
API Key: kind of random number or GUID
Pin/Secure Key/etc: Kind of password or OTP
Now, assuming that I am a third party and I want my API's to be consumed by retailers,
I would also like to create and give these credentials to API consumers.
I work in .net core. Is there any way to create these and also we have to apply security
or token based security.
I am confused because I have no idea how this can be accomlished.
As I researched a few questions on stack-overflow, they suggest to use this, or this, or some use HMAC security but in HMAC, we have to mandate client also to use HMAC so that same signatures can be matched.
I am in confused state of mind. Can you please suggest some ways by which I can do this in .net core
Generating API Keys can basically be broken down to just generating cryptographically random strings.
The following C# code snippet I had lying around generates a random hex string:
using System.Security.Cryptography;
public static string RandomString()
{
byte[] randomBytes = new Byte[64];
using (RandomNumberGenerator rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(randomBytes);
}
SHA256Cng ShaHashFunction = new SHA256Cng();
byte[] hashedBytes = ShaHashFunction.ComputeHash(randomBytes);
string randomString = string.Empty;
foreach (byte b in hashedBytes)
{
randomString += string.Format("{0:x2}", b);
}
return randomString;
}
You can easily change the length of the resulting key by using a different hash function or you can also switch the hex encoding to Base64 (Convert.ToBase64String(hashedBytes) which would replace the foreach loop) encoding which is more common when using API keys.
Edit 2022
Since when I wrote this answer both my understanding of cryptography and .NET Core itself have evolved.
Therefore nowadays I would recommend something like this
public static string GetSecureRandomString(int byteLength = 64)
{
Span<byte> buffer = byteLength > 4096
? new byte[byteLength]
: stackalloc byte[byteLength];
RandomNumberGenerator.Fill(buffer);
return Convert.ToHexString(buffer);
}
The following changes have been implemented:
using stackalloc if possible to reduce managed allocations and GC (garbage collector) pressure, thus increasing performance.
RNGCryptoServiceProvider has been deprecated and replaced with RandomNumberGenerator.Fill() or RandomNumberGenerator.GetBytes(), which also provide cryptographically sufficiently secure random bytes.
(Oversight on my part) There is actually no need for hashing in this context. The randomly generated bytes are secure as they are, so applying a hash function to them not only limits the output length (in case of SHA-256) but is also superfluous.
.NET 5 and later provide the Convert.ToHexString() method to convert bytes to hex.
I added a parameter to specify the length in bytes for the output string. More bytes = better security against brute-force attacks, but it comes with the drawback of a longer output string which may not be as handy as a shorter one. Tweak this value to fit your needs. The default is set to 512 bits (64 bytes) which is sufficiently secure for most applications.
In this example, I have chosen hex-encoding for the final string, but you may use any information-preserving encoding (hex, base64, base32, ASCII, ...) without compromising security.

Why Core Data has no type Int ? So what is best to choose from Int16 to Int64 if I have an Int?

I am working with tag's for objects on the screen using viewWithTag()
which needs an Int and also UITapGestureRecognizer will provide the tag as an Int. I am keeping track of the status of my objects in Core Data, but Core Data does not support Int (only Int16 - Int64). It's a pity now I have to convert all the time back and forward, but Ok so be it. My question is what is the best choice in Core Data for storing my Int? It is very unlikely it will surpass the 1000.
NB it gets even more funny: as I want to search the Core Data for my tag I have to search it as a string despite my type in Core Data is Int32
If you expect it to be always less than 1000, use Int16 . With this, You can still store till 2^16 - 1

Android RenderScript Allocation copy from NIO Direct ByteBuffer

On Android platform (API-19) I would like to copy a direct byte buffer into a render script allocation. Is it possible to improve the following code, for example by using NDK?
final ByteBuffer buffer = ...src;
final byte[] bytes;
if (buffer.hasArray()) {
bytes = buffer.array();
} else {
bytes = new byte[buffer.capacity()];
buffer.get(bytes);
buffer.rewind();
}
allocation.copyFromUnchecked(bytes);
Unfortunately, no. The APIs are not constructed where you can provide the backing data store for the Allocation or even retrieve an NIO based buffer that the Allocation created. The closest thing you could use would be to have a Bitmap based Allocation which was created with USAGE_SHARED so it could be sync'd as differences rather than a full copy.
It seems you can do the following:
Prepare your fixed size nio ByteBuffer
Fill the buffer in NDK (memcpy can be quite fast)
Use the yourAllocation.copyFromUnchecked(nioBuffer.array()) method
I hope it helps

File random access in J2ME

does J2ME have something similar to RandomAccessFile class, or is there any way to emulate this particular (random access) functionality?
The problem is this: I have a rather large binary data file (~600 KB) and would like to create a mobile application for using that data. Format of that data is home-made and contains many index blocks and data blocks. Reading the data on other platforms (like PHP or C) usually goes like this:
Read 2 bytes for index key (K), another 2 for index value (V) for the data type needed
Skip V bytes from the start of the file to seek to a file position there the data for index key K starts
Read the data
Profit :)
This happens many times during the program flow.
Um, and I'm investigating possibility of doing the very same on J2ME, and while I admit I'm quite new to the whole Java thing, I can't seem to be able to find anything beyond InputStream (DataInputStream) classes which don't have the basic seeking/skipping to byte/returning position functions I need.
So, what are my chances?
You should have something like this
try {
DataInputStream di = new DataInputStream(is);
di.marke(9999);
short key = di.readShort();
short val = di.readShort();
di.reset();
di.skip(val);
byte[] b= new byte[255];
di.read(b);
}catch(Exception ex ) {
ex.printStackTrace();
}
I prefer not to use the marke/reset methods, I think it is better to save the offset from the val location not from the start of the file so you can skip these methods. I think they have som issues on some devices.
One more note, I don't recommend to open a 600 KB file, it will crash the application on many low end devices, you should split this file to multiple files.

Understanding protocols

guys need some insight here.
I know the definition of a protocol, being new to this c++ programming is quite a challenging
task.I am creating a Multi-threaded chat using SDL/C++, this is a learning experience for me
and now i have encounter a hump in which I need to overcome but understanding it is a little more difficult than I had thought.I need to make a chat protocol of some sort, I think...but am stump. Up until this point i have been sending messages in strings of characters.Now that am improving the application to the point where clients can register and login, I need a better way to communicating with my clients and server.
thank you.
Create objects that represent a message, then serialize the object, send it over the network, then deserialize at the other end.
For example, you could create a class called LoginMessage that contains two fields. One for a user name, and one for a password. To login, you would do something like:
LoginMessage *msg = new LoginMessage();
msg->username = "Fred";
msg->password = "you'll never guess";
char *serialized_msg = serialize(msg);
// send the bytes over the network
You would do something similar at the other end to convert the byte stream back into an object.
There are APIs for creating message objects and serializing them for you. Here are two popular ones. Both should suit your needs.
Protocol Buffers by Google
Thrift By Facebook
If you want the serialized messages to be readable, you can use YAML. Google has an API called yaml-cpp for serializing data to YAML format.
UPDATE:
Those APIs are for making your own protocol. They just handle the conversion of messages from object form to byte stream form. They do have feature for the actual transport of the messages over the network, but you don't need to use those features. How you design your protocol it up to you. But if you want to create messages by hand, you can do that too.
I'll give you some ideas for creating your own message format.
This is one way to do it.
Have the first 4 bytes of the message represent the length of the message as an unsigned integer. This is necessary to figure out where one message ends and where the next one starts. You will need to convert between host and network byte order when reading and writing to/from these four bytes.
Have the 5th byte represent the message type. For example, you could use a 1 to indicate a login request, a 2 to indicate a login response, and 3 to indicate a chat message. This byte is necessary for interpreting the meaning of the remaining bytes.
The remaining bytes would contain the message contents. For example, if it was a login message, you would encode the username and password into these bytes somehow. If it is a chat message, these bytes would contain the chat text.

Resources