-
Notifications
You must be signed in to change notification settings - Fork 14
Upload Stream and Files
SignalGo supports streaming file(s) in an easy way and it's faster than other protocols to send or receive files and streams over the network
SignalGo uses json to serialize and deserialize data. As you know streaming is not supported natively and if you want to send byte[] data to/from server Signalgo should first convert it to json (tipically in form of base64 string), serialize and once data has been received it must be deserialized and converted back fron base64 to byte[]. This is a very slow pattern and lacks rapidly resources, leading easily to a "memory overflow" exception for large files. It's definitively inefficient. SignalGo has its own mechanism to permit to stream large files without these issues. SignalGo creates a new tcp connection inside the established connection and uses it to send or recevive stream data. It doesn't use json for bytes[] streaming! Follow these easy step to set up your raw data exchanger with SignalGo!
In new version of signalgo all services will generate automatically for client side with visual studio extension,so you can use you services very easy.
Note: your upload methods must have one StreamInfo paramter for read stream data.you can make generic for StreamInfo for send data from client to server or make it in parameters
In server side make your service methods like this example:
[ServiceContract("ProfileStorageManagerService", ServiceType.StreamService, InstanceType.SingleInstance)]
public class ProfileStorageManager
{
public MessageContract UploadProfileImage(string fileName, StreamInfo<string> streamInfo)
{
//you can use OperationContext<T> to get your client setting with client id if you dont have client plan ignore it (you can read about OperationContext in wiki too)
var currentUserSetting = OperationContext<YourSettingClass>.GetCurrent(streamInfo.ClientId);
string filePath = "your file path to save";
//this is an example to read stream and save to file
using (var fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
var lengthWrite = 0;
while (lengthWrite != streamInfo.Length)
{
byte[] bytes = new byte[1024];
var readCount = streamInfo.Stream.Read(bytes, 0, bytes.Length);
if (readCount <= 0)
break;
fileStream.Write(bytes, 0, readCount);
lengthWrite += readCount;
//if you have a progress bar in client side this code will send your server position to client and client can position it if you don't have progressbar just pervent this line
streamInfo.SetPositionFlush(lengthWrite);
}
}
//make your custom result
return MessageContract.Success();
}
}
ServerProvider provider = new ServerProvider();
//another provider plan
provider.RegisterServerService<ProfileStorageManager>();
//start your provider code
-
In signalgo new version all services will generate automatically for client side with visual studio extension,so you can use you services very easy.
-
Use your stream service in client provider (ProfileStorageManager is generated automatically in client side with visual studio code generator):
CurrentProvider = new ClientProvider();
//connect to your server
CurrentProvider.Connect("your server address to connect");
var profileStorageManagerService = new yourServerNamespace.StreamServices.ProfileStorageManager(clientProvider);
using (var stream = new File.Open("your file address on disk",FileMode.Open, FileAccess.Write, FileShare.None))
{
//automatic upload sample
var uploadResult = profileStorageManagerService.UploadProfileImage("profileimage.png", new SignalGo.Shared.Models.StreamInfo<string>() { Length = stream.Length, Stream = stream });
//manual upload sample
var streamInfo = new SignalGo.Shared.Models.StreamInfo<string>() { Data = "profileimage.png", Length = stream.Length, Stream = stream};
//when your connection is ready this action call and you can write your stream
streamInfo.WriteManually = (writeStream) =>
{
long length = stream.Length;
long position = 0;
int blockOfRead = 1024;
while (length != position)
{
if (position + blockOfRead > length)
blockOfRead = (int)(length - position);
var bytes = new byte[blockOfRead];
var readCount = stream.Read(bytes, 0, bytes.Length);
position += readCount;
writeStream.Write(bytes, 0, readCount);
//if you are using SetPositionFlush in server side use this line else ignore
var serverPosition = streamInfo.GetPositionFlush();
}
};
var uploadResult = profileStorageManagerService.UploadProfileImage("profileimage.png", streamInfo);
//your custom result
isUpload = uploadResult.IsSuccess;
}