Write to USB PORT C# using LibUsbDotNet C# USB Library - c#

I want to write some data to a USB port and receive an answer from it.
I actually used the same
string cmdLine = "#00WD3000C82B*\r";
and sent it to the same machine with the SerialPort object and by using rs235 port.
its do well.. and I got the right answer
using these methods:
omronAX.WriteAction("3000", 200.ToString("0000"));
public void WriteAction(string DM_address, string Data)
{
write_action(DM_address, Data);
}
private void write_action(string DM_address, string Data)
{
GotData = "";
Puredata = "";
EndCode = "";
try
{
int ErCd = Write_2_port("WD", DM_address, Data);
if (ErCd != 0) { return; }
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private int Write_2_port(string cod_cmd, string Addr, string Data2write)
{
DReady = false;
out_data = "";
end_c = "";
char cr = Convert.ToChar(13);
string cmd = "", Dat1 = "", Dat2 = "";
Mess = "";
Dat2 = Data2write;
if (Addr.Trim().Length > 0)
{
try
{
Dat1 = String.Format("{0:0000}", Convert.ToInt16(Addr));
}
catch (FormatException ex)
{
Mess = ex.Message;
return 1;
}
catch (OverflowException ex1)
{
Mess = ex1.Message;
return 3;
}
}
int.TryParse(Dat2, out int hex);
string hexValue = hex.ToString("X");
cmd = "#" + BakN + cod_cmd + Dat1 + hexValue ;
string send2port = cmd + Checksm(cmd) + "*" + cr;
SentCommand = send2port;
try
{
// if (Sport.IsOpen == false) { Sport.Open(); }
locking = true;
Sport.WriteTimeout = 5000;
Sport.WriteLine(send2port);
int i = 0;
while (locking)
{
if (i++ == 500)
{
throw new TimeoutException("יתכן שיש בעיות תקשורת עם המערכת.");
}
Thread.Sleep(10);
}
// T:System.ArgumentNullException:
// The str parameter is null.
//
// T:System.InvalidOperationException:
// The specified port is not open.
//
// T:System.TimeoutException:
// The System.IO.Ports.SerialPort.WriteLine(System.String) method could not write
// to the stream.
}
catch (TimeoutException ex)
{
Mess = ex.Message;
throw ex;
}
catch (Exception ex)
{
Mess = ex.Message;
return 2;
}
return 0;
}
for the next code, I try using USB port and write to it the same line...
But I got nothing when I read the answer back and I got (bytesRead = 0)
in my bytesWritten, I got 15...
using System;
using System.Text;
using System.Text.RegularExpressions;
using LibUsbDotNet;
using LibUsbDotNet.Main;
namespace Examples
{
internal class ReadWrite
{
public static UsbDevice MyUsbDevice;
#region SET YOUR USB Vendor and Product ID!
public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x0590,0x005B);
#endregion
public static void Main(string[] args)
{
ErrorCode ec = ErrorCode.None;
try
{
// Find and open the USB device.
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
// If the device is open and ready
if (MyUsbDevice == null) throw new Exception("Device Not Found.");
// If this is a "whole" usb device (libusb-win32, linux libusb)
// it will have an IUsbDevice interface. If not (WinUSB) the
// variable will be null indicating this is an interface of a
// device.
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// This is a "whole" USB device. Before it can be used,
// the desired configuration and interface must be selected.
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
wholeUsbDevice.ClaimInterface(0);
}
// open read endpoint 1.
UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
// open write endpoint 1.
UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
// Remove the exepath/startup filename text from the begining of the CommandLine.
//string cmdLine = Regex.Replace(Environment.CommandLine, "^\".+?\"^.*? |^.*? ", "", RegexOptions.Singleline);
string cmdLine = "#00WD3000A11*\r";
if (!String.IsNullOrEmpty(cmdLine))
{
int bytesWritten;
ec = writer.Write(Encoding.Default.GetBytes(cmdLine), 20000000, out bytesWritten);
if (ec != ErrorCode.None) throw new Exception(UsbDevice.LastErrorString);
byte[] readBuffer = new byte[1024];
while (ec == ErrorCode.None)
{
int bytesRead;
// If the device hasn't sent data in the last 100 milliseconds,
// a timeout error (ec = IoTimedOut) will occur.
ec = reader.Read(readBuffer, 100, out bytesRead);
if (bytesRead == 0) throw new Exception("No more bytes!");
// Write that output to the console.
Console.Write(Encoding.Default.GetString(readBuffer, 0, bytesRead));
}
Console.WriteLine("\r\nDone!\r\n");
}
else
throw new Exception("Nothing to do.");
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine((ec != ErrorCode.None ? ec + ":" : String.Empty) + ex.Message);
}
finally
{
if (MyUsbDevice != null)
{
if (MyUsbDevice.IsOpen)
{
// If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
// it exposes an IUsbDevice interface. If not (WinUSB) the
// 'wholeUsbDevice' variable will be null indicating this is
// an interface of a device; it does not require or support
// configuration and interface selection.
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// Release interface #0.
wholeUsbDevice.ReleaseInterface(0);
}
MyUsbDevice.Close();
}
MyUsbDevice = null;
// Free usb resources
UsbDevice.Exit();
}
// Wait for user input.
Console.ReadKey();
}
}
}
}
I have no idea and I am doing wrong, thanks.

I recommend using Usb.Net (https://github.com/MelbourneDeveloper/Device.Net) instead of LibUsb. The problem with LibUsb is that is just wraps WinUSB calls. So, you are deploying an extra C dll (LibUsb) that just points to an existing Windows C DLL. LibUsb is good if you want to keep the code cross platform with Linux, but otherwise, there's not much point.
Here is sample WinUsb code (https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Usb.Net/Windows/WindowsUsbDevice.cs)
public override Task InitializeAsync()
{
Dispose();
int errorCode;
if (string.IsNullOrEmpty(DeviceId))
{
throw new WindowsException($"{nameof(DeviceDefinition)} must be specified before {nameof(InitializeAsync)} can be called.");
}
_DeviceHandle = APICalls.CreateFile(DeviceId, (APICalls.GenericWrite | APICalls.GenericRead), APICalls.FileShareRead | APICalls.FileShareWrite, IntPtr.Zero, APICalls.OpenExisting, APICalls.FileAttributeNormal | APICalls.FileFlagOverlapped, IntPtr.Zero);
if (_DeviceHandle.IsInvalid)
{
//TODO: is error code useful here?
errorCode = Marshal.GetLastWin32Error();
if (errorCode > 0) throw new Exception($"Device handle no good. Error code: {errorCode}");
}
var isSuccess = WinUsbApiCalls.WinUsb_Initialize(_DeviceHandle, out var defaultInterfaceHandle);
HandleError(isSuccess, "Couldn't initialize device");
var bufferLength = (uint)Marshal.SizeOf(typeof(USB_DEVICE_DESCRIPTOR));
isSuccess = WinUsbApiCalls.WinUsb_GetDescriptor(defaultInterfaceHandle, WinUsbApiCalls.DEFAULT_DESCRIPTOR_TYPE, 0, 0, out _UsbDeviceDescriptor, bufferLength, out var lengthTransferred);
HandleError(isSuccess, "Couldn't get device descriptor");
byte i = 0;
//Get the first (default) interface
var defaultInterface = GetInterface(defaultInterfaceHandle);
_UsbInterfaces.Add(defaultInterface);
while (true)
{
isSuccess = WinUsbApiCalls.WinUsb_GetAssociatedInterface(defaultInterfaceHandle, i, out var interfacePointer);
if (!isSuccess)
{
errorCode = Marshal.GetLastWin32Error();
if (errorCode == APICalls.ERROR_NO_MORE_ITEMS) break;
throw new Exception($"Could not enumerate interfaces for device {DeviceId}. Error code: { errorCode}");
}
var associatedInterface = GetInterface(interfacePointer);
_UsbInterfaces.Add(associatedInterface);
i++;
}
IsInitialized = true;
RaiseConnected();
return Task.CompletedTask;
}
However, I did submit this sample to LibUsbDotNet and it's now the accepted Read/Write sample there (https://github.com/LibUsbDotNet/LibUsbDotNet/blob/master/src/Examples/Read.Write/ReadWrite.cs):
public static void Main(string[] args)
{
using (var context = new UsbContext())
{
context.SetDebugLevel(LogLevel.Info);
//Get a list of all connected devices
var usbDeviceCollection = context.List();
//Narrow down the device by vendor and pid
var selectedDevice = usbDeviceCollection.FirstOrDefault(d => d.ProductId == ProductId && d.VendorId == VendorId);
//Open the device
selectedDevice.Open();
//Get the first config number of the interface
selectedDevice.ClaimInterface(selectedDevice.Configs[0].Interfaces[0].Number);
//Open up the endpoints
var writeEndpoint = selectedDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
var readEnpoint = selectedDevice.OpenEndpointReader(ReadEndpointID.Ep01);
//Create a buffer with some data in it
var buffer = new byte[64];
buffer[0] = 0x3f;
buffer[1] = 0x23;
buffer[2] = 0x23;
//Write three bytes
writeEndpoint.Write(buffer, 3000, out var bytesWritten);
var readBuffer = new byte[64];
//Read some data
readEnpoint.Read(readBuffer, 3000, out var readBytes);
}
}

I had an issue getting my device to connect with another library because I was using upper case for alphabetic characters in the VID/PID. Have you tried using lower case ("0x005b" instead of "0x005B")?

Related

Why is my BLE device data FFFFFFF from config index?

Basically, I am supposed to retrieve a value from a Bluetooth LE skincare device. Among the services that the device has, the device has a configuration service, with two characteristics: one for reading/writing data, and another characteristic for reading and writing the configuration value.
I have the document that shows all the UUID's, their characteristics, properties, values etc. The configuration indexes are all listed in the file too, and preprogrammed in the device.
Goal: This is where I am stuck. One of the config indexes has a value of 12. I have to write the config index to the characteristic, and then in return, the program will read the data corresponding to the configuration index, and print the data on the terminal. I sent a value as 0C (12 in hex), and ended up with FFFFFFFFFFFFFFFFFFFF. It has to be a different value.
How can I achieve this goal?
This is the code that I have so far:
while (true)
{
if (device == null)
{
Thread.Sleep(200);
}
else
{
Console.WriteLine("Press any key to pair the device.");
Console.ReadKey();
Console.WriteLine();
BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
Console.WriteLine("Attempting to pair with device");
GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var services = result.Services;
foreach (var service in services)
{
if (service.Uuid.ToString() == configSvc)
{
GattCharacteristicsResult charactiristicResult = await service.GetCharacteristicsAsync();
if (charactiristicResult.Status == GattCommunicationStatus.Success)
{
var characteristics = charactiristicResult.Characteristics;
foreach (var characteristic in characteristics)
{
GattReadResult rResult = await characteristic.ReadValueAsync();
GattCharacteristicProperties properties = characteristic.CharacteristicProperties;
if (properties.HasFlag(GattCharacteristicProperties.Write))
{
var writer = new DataWriter();
GattCommunicationStatus wResult = await characteristic.WriteValueAsync(writer.DetachBuffer());
if (characteristic.Uuid.ToString() == configIdxCt)
{
int psCalVal = 12;
//var startCommand = Encoding.ASCII.GetBytes(psCalVal.ToString());
//Console.WriteLine(startCommand[0]);
writer.WriteByte(0xc0);
if (wResult == GattCommunicationStatus.Success)
{
Console.WriteLine("message sent successfully");
}
else
{
Console.WriteLine("Error encountered on writing to characteristic!");
}
}
}
if(properties.HasFlag(GattCharacteristicProperties.Read))
{
if (rResult.Status == GattCommunicationStatus.Success)
{
if (characteristic.Uuid.ToString() == configValCt)
{
var reader = DataReader.FromBuffer(rResult.Value);
byte[] input = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(input);
//Console.WriteLine(input[0]);
Console.WriteLine("Data: ");
string psCArrayWDash = BitConverter.ToString(input) + " ";
string psCArray = psCArrayWDash.Replace("-", "").ToLower();
Console.WriteLine(psCArray);
}
if (characteristic.Uuid.ToString() == measurementCt)
{
Console.WriteLine("Read");
var reader = DataReader.FromBuffer(rResult.Value);
byte[] input = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(input);
Console.WriteLine("Data: ");
for (int i = 0; i < input.Length; i++)
Console.WriteLine(input[i].ToString() + " ");
}
}
else
Console.WriteLine("ERROR");
}
}
}
}
}
}
else
Console.WriteLine("Please, make sure the device is connected, and try again.");
}
}
deviceWatcher.Stop();

Downloading file parts using HttpWebRequest C#

I am trying to download a 100GB file using HttpWebRequest. The download will be split into parts depending on a preset part size. Below is the code I use to download the file:
private static void AddRangeHeaderHack(WebHeaderCollection headers, long start, long end)
{
// Original workaround by Eric Cadwell, code taken from
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93714
Type type = headers.GetType();
System.Reflection.MethodInfo setAddVerified = type.GetMethod("SetAddVerified",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy
);
string rangeHeaderValue = String.Format("bytes={0}-{1}", start, end);
if (setAddVerified != null)
setAddVerified.Invoke(headers, new object[] { "Range", rangeHeaderValue });
}
private ulong GetRemoteFileSize(string URI)
{
ulong size = 0;
HttpWebRequest req = null;
try
{
req = (HttpWebRequest)WebRequest.Create(URI);
using (var res = (HttpWebResponse)req.GetResponse())
{
size = (ulong)res.ContentLength;
res.Close();
}
}
catch (Exception ex)
{
}
if (req != null)
{
try
{
req.Abort();
req = null;
}
catch (Exception)
{
}
}
return size;
}
private int DownloadFromLink(string sSource, string sDestination)
{
int nRetryCount = 0;
int nMaxRetry = 5;
var lastProgress = DateTime.Now;
ulong offset = 0;
var bRetrying = false;
var bResumable = false;
var fileSize = GetRemoteFileSize(sSource);
if (fileSize > 0)
bResumable = true;
while (true)
{
HttpWebRequest webRequest = null;
try
{
try
{
bRetrying = false;
do
{
try
{
if (bDownloadAbort)
{
return -1;
}
webRequest = (HttpWebRequest)WebRequest.Create(sSource);
webRequest.Timeout = 3600000;
if (offset > 0)
{
AddRangeHeaderHack(webRequest.Headers, (long)offset, (long)fileSize);
}
// Retrieve the response from the server
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
var acceptRanges = String.Compare(webResponse.Headers["Accept-Ranges"], "bytes", true) == 0;
// Open the URL for download
using (var streamResponse = webResponse.GetResponseStream())
{
if (streamResponse != null)
{
// Create a new file stream where we will be saving the data (local drive)
using (var streamLocal = new FileStream(sDestination, offset>0?FileMode.Append:FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
// It will store the current number of bytes we retrieved from the server
int bytesSize = 0;
// A buffer for storing and writing the data retrieved from the server
byte[] downBuffer = new byte[/*16384*/ 1024 * 1024];
bool binitialtry = true;
int nRetries = 0;
if (offset > 0)
{
streamLocal.Seek((long)offset, SeekOrigin.Begin);
}
// Loop through the buffer until the buffer is empty
while ((bytesSize = streamResponse.Read(downBuffer, 0, downBuffer.Length)) > 0
|| (File.Exists(sDestination) && (offset < (ulong)fileSize) && nRetries < 5 && bResumable))
{
if (binitialtry && bytesSize == 0)
{
binitialtry = false;
}
if (!binitialtry && bytesSize == 0)
{
nRetries++;
bRetrying = nRetries<5;
break;
}
if (bDownloadAbort)
{
try { streamLocal.Close(); }
catch { }
return;
}
try
{
// Write the data from the buffer to the local hard drive
streamLocal.Write(downBuffer, 0, bytesSize);
offset += (ulong)bytesSize;
}
catch (IOException ex)
{
if (streamResponse != null)
streamResponse.Close();
if (streamLocal != null)
streamLocal.Close();
if (webRequest != null)
webRequest.Abort();
return -1;
}
Interlocked.Add(ref actualDownloaded, bytesSize);
}
// When the above code has ended, close the streams
if (streamResponse != null)
streamResponse.Close();
if (streamLocal != null)
try { streamLocal.Close(); }
catch { }
if (webRequest != null)
webRequest.Abort();
if (webRequest != null)
wcDownload.Dispose();
streamLocal.Close();
}
streamResponse.Close();
}
}
webResponse.Close();
}
if(!bRetrying)
break;
}
catch (IOException ex)
{
if (webRequest != null)
webRequest.Abort();
if (wcDownload != null)
wcDownload.Dispose();
if (nRetryCount <= nMaxRetry)
{
Thread.Sleep(10000);
nRetryCount++;
bRetrying = true;
}
else
{
break;
}
}
catch (UnauthorizedAccessException ex)
{
if (webRequest != null)
webRequest.Abort();
break;
}
catch (WebException ex)
{
if (webRequest != null)
webRequest.Abort();
if (wcDownload != null)
wcDownload.Dispose();
if (nRetryCount <= nMaxRetry)
{
Thread.Sleep(10000);
nRetryCount++;
bRetrying = true;
}
else
{
break;
}
}
finally
{
}
} while (bRetrying);
}
catch (Exception ex)
{
break;
}
}
catch
{
break;
}
if(!bRetrying)
break;
}
}
If I try to download the file in 1 part, with out adding the range header, the code runs smoothly and the file downloads normally. When I add a range header, say from 10GB to 15GB or frankly any value, the code reaches streamResponse.Read and hangs there for several minutes then it throws an exception:
Unable to read data from the transport connection: An existing
connection was forcibly closed by the remote host
When the code retries the connection after the exception, the download resumes normally and the client is able to read data from the stream.
Can someone help me determine why such thing is happening?
Just to clear the matter about the server, the file is currently hosted on an Amazon S3 server, and the download is done from a generated direct link.
It could be a server setting, according to http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4
Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.
Try FDM, and see if it has a problem. http://www.freedownloadmanager.org/
I don’t know how to download a file in parts using HttpWebRequest, but I found this example online to build an own implementation. The article is about the HttpClient in C#. There is also complete code and project you can find in the download section of this page.
The Problem is that not all server support partial download. So NuGet packages can be used that handle the exceptions e.g.:
https://www.nuget.org/packages/downloader
or
https://www.nuget.org/packages/Shard.DonwloadLibrary.
These Libraries will handle the chunks and convert them back into a readable file or stream.
Downloader:
var downloader = new DownloadService(new()
{
ChunkCount = 8,
});
string file = #"Your_Path\fileName.zip";
string url = #"https://file-examples.com/fileName.zip";
await downloader.DownloadFileTaskAsync(url, file);
or Download Library:
string file = "Your_Path";
string url = "https://file-examples.com/fileName.zip";
var downloader = new LoadRequest(url,new()
{
Chunks = 8,
DestinationPath= file,
});
await downloader.Task;
I hope I could help!

Parallel.Foreach do not finish stream

For load testing purposes I need to simulate multiple users trying to login to a system at the same time. I have code written by another developer that can send a login request to the system. With an ok login it will also return other information in xml.
I've tried using Parallel.ForEach, but dont have any real experience with parallel programming:
Parallel.ForEach(clientList, client =>
{
RunTest(client);
});
public void RunTest(object data)
{
if (!(data is IGprsClient))
{
return;
}
_noRunningTests += 1;
IGprsClient gprsClient = data as IGprsClient;
DateTime startTime = DateTime.Now;
Log(gprsClient.Id, "Test started.");
bool result = gprsClient.StartTest(20000);
DateTime endTime = DateTime.Now;
TimeSpan diff = endTime - startTime;
if (result == false)
{
Log(gprsClient.Id, "Test failed.");
}
Log(gprsClient.Id, "Test took {0}ms. ", (int)diff.TotalMilliseconds);
_noRunningTests -= 1;
}
override public bool StartTest(int timeout)
{
_testStarted = true;
try
{
LogDebug("Trying to connect.");
_client = new TcpClient(ipAddress, port);
LogDebug("Connected.");
bool result = false;
//Todo: insert testcase into client
switch (TestCaseName)
{
case "LoginTEST":
var testCase = new LoginTEST(this);
result = testCase.Execute(user, pwd, phoneNum);
break;
default:
Log("Unknown test case: " + TestCaseName);
break;
}
_client.Close();
return result;
}
catch (Exception ex)
{
if (_client != null)
_client.Close();
Log(ex.Message);
return false;
}
}
Which in turn will send the request and read the response.
public bool Execute(string user, string pwd, string phoneNum)
{
SendDataListRequest(userId);
string requiredDataResponse = Client.ReadMsg();
return true;
}
Run test will send a request and reads the message like so:
public string ReadMsg()
{
int msgLength = -1;
var stream = _client.GetStream();
while (_testStarted)
{
int b = stream.ReadByte();
if (b == -1)
{
return "";
}
else if (b == 0x02 || msgLength == -1)
{
while (b != 0x02 && _testStarted)
{
b = stream.ReadByte(); // Finds the start token
if (b == -1)
{
return "";
}
}
msgLength = 0; // Starts collecting data
}
else if (b == 0x03)
{
byte[] encryptedMsg = Convert.FromBase64String(
Encoding.UTF8.GetString(byteBuffer, 0, msgLength));
byte[] decryptedMsg = SttCipher.DecryptMessage(encryptedMsg);
MemoryStream ms = new MemoryStream(decryptedMsg);
GZipStream gZipStream = new GZipStream(ms, CompressionMode.Decompress, true);
var bufLen = ReadAllBytesFromStream(gZipStream, decompressedBuffer);
gZipStream.Close();
string completeMsg = Encoding.UTF8.GetString(decompressedBuffer, 0, bufLen);
if (completeMsg.Length < 500)
LogDebug("Received XML-data:\n{0}", completeMsg);
else
LogDebug("Received XML-data: {0} bytes\n{1}...", completeMsg.Length, completeMsg.Substring(0, 500));
return completeMsg;
}
else
{
if (byteBuffer.Length <= msgLength)
{
throw new Exception("XML message too long!");
}
byteBuffer[msgLength] = (byte)b;
msgLength++;
}
}
return "";
}
Running one client is fine and will wait for the response. The issue is with several clients, the responses gets cut off. Leaving me with unclosed xml in the response.But I cant't figure out why. Does anyone have a reasonable explanation and/or a solution or a better way of doing it?

EventStore duplicate commit exception

UPDATE:
We are getting getting System.Data.SqlClient.SqlException. The message is:
Violation of PRIMARY KEY constraint 'PK_Commits'. Cannot insert duplicate key in object 'dbo.Commits'.\r\nThe statement has been terminated
It seems like EventStore is using streamid and commitid as unique id.
We use event store to append events as below.
public bool TryAppend(object[] content)
{
if (content == null)
throw new ArgumentNullException("content");
try
{
using (var stream = m_storage.OpenStream(m_streamID, 0, int.MaxValue))
{
var versionInStore = stream.StreamRevision;
content.ToList().ForEach(m =>
{
var version = ++versionInStore;
var key = string.Format("{0}-{1:00000000}", m.GetType().Name, version);
var savedMessage = new SavedRecord(key, version, m);
stream.Add(new EventMessage { Body = savedMessage });
});
stream.CommitChanges(Guid.NewGuid());
}
return true;
}
catch (Exception e)
{
m_logger.LogError(e);
return false;
}
}
The configuration of EventStore is as below. We are using Sql Serer 2008 as persistance store.
return Wireup.Init()
.LogToOutputWindow()
.UsingSqlPersistence(m_connectionName)
.WithDialect(new MsSqlDialect())
.EnlistInAmbientTransaction() // two-phase commit
.InitializeStorageEngine()
.UsingJsonSerialization()
.Compress()
.UsingSynchronousDispatchScheduler()
.DispatchTo(new DelegateMessageDispatcher(DispatchCommit))
.Build();
Any ideas why are gettin the dupplicate commit exception?
Thanks
Have got the same issue; in my case it was probably because of different threads was adding different events to the stream with same id at the same time.
Have writtent the following code to be able to retry adding events:
private void TryAddEvent(IStoreEvents storeEvents, IUserEvent anEvent, Guid streamId)
{
var isCommitSuccessful = false;
for (var i = 0; i < 10 && !isCommitSuccessful; i++)
{
try
{
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
stream.Add(new EventMessage {Body = anEvent});
if (stream.UncommittedEvents.All(e => e.Body != anEvent))
{
stream.Add(new EventMessage {Body = anEvent});
}
stream.CommitChanges(Guid.NewGuid());
}
isCommitSuccessful = true;
}
catch (Exception ex)
{
if (!(ex is SqlException) && !(ex is ConcurrencyException))
{
throw;
}
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
if (stream.CommittedEvents.Any(e => e.Body == anEvent))
{
isCommitSuccessful = true;
}
}
}
}
if (!isCommitSuccessful)
{
throw new ConcurrencyException(String.Format("Cannot add {0} to event store", anEvent.GetType()));
}
}
Hope it would help.

How to convert byte into Boolean

I want to convert a byte into Boolean. This is the code:
String text = textBox1.Text;
UdpClient udpc = new UdpClient(text,8899);
IPEndPoint ep = null;
while (true)
{
MessageBox.Show("Name: ");
string name = "Connected";
if (name == "") break;
byte[] sdata = Encoding.ASCII.GetBytes(name);
udpc.Send(sdata, sdata.Length);
if (udpc.Receive(ref ep)=null)
{
// MessageBox.Show("Host not found");
}
else
{
byte[] rdata = udpc.Receive(ref ep);
string job = Encoding.ASCII.GetString(rdata);
MessageBox.Show(job);
}
}
I want to convert this line of code into a Boolean:
udpc.Receive(ref ep);
You don't want to just compare the result with null at all... that way you would lose the actual data, and then call Receive again, effectively skipping the packet.
You should use:
byte[] data = udpc.Receive(ref ep);
if (data == null)
{
// Whatever
}
else
{
MessageBox.Show(Encoding.ASCII.GetBytes(data));
}
Also note that this code is broken:
string name = "Connected";
if (name == "") break;
How can name possibly be an empty string when you've just set it to "Connected"?
The UdpClient is naturally blocking until bytes are received.
This means that you shouldn't get data at all, assuming that you're looking for a way to indicate if you have received data, then once you move past the udpc.Recieve, you should return true.
I would also consider changing the code a bit as you will have some compilation issues with the = null statement as this does not translate into a compilable code expression.
There is also a problem with your if else statement as you're attempting to read from the UDP client which would consume the sent data.
Personally I would opt for a UDP socket, but in order to get you rolling I would change the code to something like this:
String text = textBox1.Text;
UdpClient udpc = new UdpClient(text,8899);
IPEndPoint ep = null;
while (true)
{
MessageBox.Show("Name: ");
string name = "Connected";
if (name == "") break; //This will never happen because you have already set the value
byte[] sdata = Encoding.ASCII.GetBytes(name);
int dataSent = 0;
try
{
dataSent = udpc.Send(sdata, sdata.Length);
}
catch(Exception e)
{
dataSent = 0;
//There is an exception. Probably the host is wrong
}
if (dataSent > 0)
{
try
{
byte[] rdata = udpc.Receive(ref ep);
if(rdata!=null && rdata.Length > 0)
{
string job = Encoding.ASCII.GetString(rdata);
MessageBox.Show(job)
//True here as we managed to recieve without going to the catch statement
//and we actually have data in the byte[]
}
else
{
MessageBox.Show("We did not recieve any data");
//False here, because the array was empty.
}
}
catch(Exception udpe)
{
//False here as we had a socket exception or timed out
MessageBox.Show(udpe.ToString());
}
}
}

Categories