We are using the websocket-sharp in one of our applications which establishes a websocket connection with our SignalR Hub on the server, we are able to send the text messages and receive the response for the same but unable to post a byte[].
Code for sending text to server is this:
public void TestGroupData(string groupname)
{
DataCarrier dataCarrier = new DataCarrier()
{
H = "BILHub",
M = "GetAllGroupsFor",
A = new string[] { groupname }
};
string wsPacket = JsonConvert.SerializeObject(payLoad);
this._ws.Send(wsPacket);
//this.MakeServerCall(dataCarrier);
}
When we try to send byte[] using the below code, its not going through:
public void TestFileData()
{
try
{
// Read the file data
Console.WriteLine("Started reading file");
string fileName = #"C:\Saurabh\Data\Song.mp3";
byte[] file = File.ReadAllBytes(fileName);
DataCarrier dataCarrier = new DataCarrier()
{
H = "BILHub",
M = "SendFile",
A = new object[] { file }
};
string wsPacket = JsonConvert.SerializeObject(dataCarrier);
this._ws.SendAsync(file , OnSendComplete);
}
catch (Exception ex)
{
Console.WriteLine(ex);
//throw;
}
}
Any help with this? How can I set my hub name in _ws.sendAsync()?
Sending big files is not really what SignalR is meant for.
SignalR is good for real-time messaging purposes between server & clients, for a rather small sized messages (as messahe size has a real impact on performance).
For such a need I would look into ASP.NET Web API, especially by using chunked upload (splitting file in multiple pieces to avoid connection interruptions)
Related
Title sums it up. There are plenty of examples around with a c# server and python client communicating back and forth.
I'd like to understand how I can instead create a python server and c# client for some interprocess communication.
I managed to find a solution. To begin, I'd first like to clarify some confusing terminology and obscure naming conventions used in dotnet core.
It appears that the NamedPipeServerStream and NamedPipeClientStream don't actually operate on named pipes but instead on unix domain sockets. This means that we must use sockets to communicate between processes rather than FIFO files.
Another frustration I find with dotnet core is that when creating a socket or connecting to one, the NamedPipeServerStream and NamedPipeClientStream classes will add "CoreFxPipe_" to the beginning of the socket name. See related question.
Python Server
#!/usr/bin/python3
import socket
import os
import struct
SOCK_PATH = "/tmp/CoreFxPipe_mySocket"
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
try:
os.remove(SOCK_PATH)
except OSError:
pass
sock.bind(SOCK_PATH)
sock.listen()
conn, addr = sock.accept()
with conn:
try:
while True:
amount_expected = struct.unpack('I', conn.recv(4))[0]
print("amount_expected :", amount_expected)
message = conn.recv(amount_expected)
print("Received message : ", message.decode())
# Send data
message_rev = message[::-1].decode()
print("Sent message (reversed) : ", message_rev)
conn.sendall(
struct.pack(
'I',
len(message_rev)
)
+ message_rev.encode('utf-8')
)
except (struct.error, KeyboardInterrupt) as e:
print(e)
finally:
print('closing socket')
C# Client
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
class PipeClient
{
static void Main(string[] args)
{
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "mySocket", PipeDirection.InOut))
{
// Connect to the pipe or wait until the pipe is available.
Console.WriteLine("Attempting to connect to pipe...");
pipeClient.Connect();
try
{
// Read user input and send that to the client process.
using (BinaryWriter _bw = new BinaryWriter(pipeClient))
using (BinaryReader _br = new BinaryReader(pipeClient))
{
while (true)
{
//sw.AutoFlush = true;
Console.Write("Enter text: ");
var str = Console.ReadLine();
var buf = Encoding.ASCII.GetBytes(str); // Get ASCII byte array
_bw.Write((uint)buf.Length); // Write string length
_bw.Write(buf); // Write string
Console.WriteLine("Wrote: \"{0}\"", str);
Console.WriteLine("Let's hear from the server now..");
var len = _br.ReadUInt32();
var temp = new string(_br.ReadChars((int)len));
Console.WriteLine("Received from client: {0}", temp);
}
}
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}
Console.Write("Press Enter to continue...");
}
}
Sources:
https://abgoswam.wordpress.com/2017/07/13/named-pipes-c-python-net-core/
https://realpython.com/python-sockets/
https://unix.stackexchange.com/questions/75904/are-fifo-pipe-unix-domain-socket-the-same-thing-in-linux-kernel
I am writing a web app for the Gear S3 and a companion Win-App for UWP in C#.
What I want it to do: S3 acting as a BT server, sending data, and the Win-App as a client, which is supposed to receive the data.
In Tizen I used the registerRfcommServiceByUUID() function as below:
function publishTransferService() {
if(remoteDevice.isConnented){
console.log("Connection Status: " + remoteDevice.isConnected);
var TRANS_SERVICE_UUID = '5BCE9431-6C75-32AB-AFE0-2EC108A30860';
adapter.registerRFCOMMServiceByUUID(TRANS_SERVICE_UUID, 'My Service', ServiceSuccessCb,
function(e) {
console.log( "Could not register service record, Error: " + e.message);
});
}else{
console.error("Connection Status: " + remoteDevice.isConnected);
}
In C# i try to connect to the service as follows:
//to ulong converted MAC-Address of the Gear
ulong gearBtAddress = 145914022804881;
//create device-instance of the gear
BluetoothDevice gearDevice = await BluetoothDevice.FromBluetoothAddressAsync(gearBtAddress);
//list the services found on the gear and connect to the one with
//the same uuid as in tizen
var gearServices = await gearDevice.GetRfcommServicesAsync();
foreach (var service in gearServices.Services)
{
if(service.ServiceId == RfcommServiceId.FromUuid(Guid.Parse("5BCE9431-6C75-32AB-AFE0-2EC108A30860")))
{
_service = await RfcommDeviceService.FromIdAsync(service.ToString());
}
}
The Problem I am facing is, that the C# won't find the wanted Uuid, although it finds several other uuids. I don't see where it gets lost?
Thanks in advance.
I solved it myself, the problem was, that the UUID was uncached. Adding the following was all to do:
var cacheMode = BluetoothCacheMode.Uncached;
var gearServices = await gearDevice.GetRfcommServicesAsync(cacheMode);
I have two applications. The server send files to my clients. The clients are implemented in Unity3d with C#. Each client has one thread to receive files from server. If I send the files over the network, I write the bytes to the file with this code:
private Thread clientThread;
private object writeLock = new object();
public void StartConnection()
{
// Start connection to server.
clientThread = new Thread(GetFiles);
}
public void GetFiles()
{
string fullPath;
// Receive bytes from server
fullPath = Path.Combine(clientDirPath, fileNameFromServer);
lock(writeLock)
{
using (BinaryWriter bWrite = new BinaryWriter(File.Open(fullPath, FileMode.Create)))
{
bWrite.Write(binaryFileContent);
bWrite.Flush();
}
}
Now, if I start multple clients and send files to receive them synchronously on the client-side, I get this error message: System.IO.IOException:Sharing violation on path. Whether I use the lock-statement it is not working. Do anyone know the way to get it working?
EDIT: I added more code.
I have this web api where I'm posting images to a folder in my web api and it works fine when doing it locally but when publishing the web api online it doesn't work and throws the following error message "Error writing MIME multipart body part to output stream". I've seen a few people with similar questions but i havent been able to solve it therefore im putting the code out there and hopefully someone could notice what may be causing this! here is the code:
public async Task<HttpResponseMessage> Post()
{
// Check whether the POST operation is MultiPart?
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
// Prepare CustomMultipartFormDataStreamProvider in which our multipart form
// data will be loaded.
string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data");
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
List<string> files = new List<string>();
try
{
// Read all contents of multipart message into CustomMultipartFormDataStreamProvider.
//Here the code goes down to public class CustomMultipartFormDataStreamProvider and runs that code and then jump back here. When it gets back here is when the Error is Thrown
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData file in provider.FileData)
{
files.Add(Path.GetFileName(file.LocalFileName));
}
// Send OK Response along with saved file names to the client.
return Request.CreateResponse(HttpStatusCode.OK, files);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
The code is from http://www.intstrings.com/ramivemula/articles/file-upload-using-multipartformdatastreamprovider-in-asp-net-webapi/ where you can read more about the code. Any help or input highly appreciated, thanks!
I am not sure you can store data in the App_Data.
It will be a thousand times better if you store all your files in the Blob storage. If you need any help I will assist.
Follow this article and you will get it running.
https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/
Make sure the virtual directory (~/App_Data directory as below example) where the image files are first uploaded are physically existence. When you publish the project, it may not be in the output files.
string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data"); CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
Hey i was wondering if you could help me
I'm creating an android application in html5 and java script.
There are a server that is created on c# that is listing connection.
I can connect the 2 apps together but get i can get the c# app to reply to my android application using javascript.
here is my server code
public void Listeners()
{
Socket socketForClient = tcpListener.AcceptSocket();
if (socketForClient.Connected)
{
nr_connections = nr_connections + 1;
nr_qry = nr_qry + 1;
SetText("");
SetText("New Connection.");
NetworkStream networkStream = new NetworkStream(socketForClient);
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
streamWriter.Flush();
string GettheString = streamReader.ReadLine();
if (GettheString == "server_status")
{
SetText("Checking Server Status.");
streamWriter.WriteLine("Online");
streamWriter.Close();
streamReader.Close();
networkStream.Close();
}
}
socketForClient.Close();
SetText("Connection Closed...");
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
nr_connections = nr_connections - 1;
}
and my javascript code
function connect ()
{
try
{
var connection = new WebSocket('ws://105.237.125.247:8');
connection.onopen = function ()
{
connection.send('server_status');
};
connection.onmessage = function (event) {
alert(event.data);
}
}
catch(Exeption)
{
alert("Check Connection");
}
}
Im getting data from the android app but can send back to the javascript file
Web-sockets is a protocol that sits on top of a regular transport (such as a socket); basically, you need a web-socket library. If you are using recent versions of Windows, then much of this is baked into HTTP.SYS, and available via HttpListnener (in particular, AcceptWebSocketAsync on a context). However, alternative web-socket libraries are available, or can be written from scratch if you so choose.