[英]Read data from StreamSocketListener on RFComm bluetooth connected device C#
我正在开发通用应用程序Win8.1 / WP8.1,我能够发现并连接到配对的蓝牙设备(Stick阅读器-Rfid)
这就是我的联系方式
变量
private IAsyncOperation<RfcommDeviceService> connectService;
private IAsyncAction connectAction;
private RfcommDeviceService rfcommService;
private RfcommServiceProvider rfcommProvider;
private StreamSocketListener listener;
private DataReader reader;
private DataWriter writer;
//连接
public async Task ConnectToServiceAsync(string name)
{
DeviceInformation serviceInfo = null;
foreach (var device in devices)
{
if(device.Name == name)
{
serviceInfo = device;
break;
}
}
if (serviceInfo != null)
{
this.State = BluetoothConnectionState.Connecting;
try
{
// Initialize the target Bluetooth RFCOMM device service
connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);
rfcommService = await connectService;
if (rfcommService != null)
{
rfcommProvider = await RfcommServiceProvider.CreateAsync(rfcommService.ServiceId);
// Create a socket and connect to the target
listener = new StreamSocketListener();
listener.ConnectionReceived += Listener_ConnectionReceived;
connectAction = listener.BindServiceNameAsync(rfcommService.ServiceId.AsString(), SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
await connectAction;//to make it cancellable
writer = new DataWriter(socket.OutputStream);
reader = new DataReader(socket.InputStream);
this.State = BluetoothConnectionState.Connected;
}
else
OnExceptionOccuredEvent(this, new Exception("Unable to create service.\nMake sure that the 'bluetooth.rfcomm' capability is declared with a function of type 'name:serialPort' in Package.appxmanifest."));
}
catch (TaskCanceledException)
{
this.State = BluetoothConnectionState.Disconnected;
}
catch (Exception ex)
{
this.State = BluetoothConnectionState.Disconnected;
OnExceptionOccuredEvent(this, ex);
}
}
}
//然后等待通过侦听器的连接
private async void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
DataReader inputreader = new DataReader(args.Socket.InputStream);
while (true)
{
try
{
inputreader.InputStreamOptions = InputStreamOptions.Partial;
// Read first byte (length of the subsequent message, 255 or less).
uint sizeFieldCount = await inputreader.LoadAsync(1);
if (sizeFieldCount != 1)
{
// The underlying socket was closed before we were able to read the whole data.
return;
}
// Read the message.
uint messageLength = inputreader.ReadByte();
uint actualMessageLength = await inputreader.LoadAsync(messageLength);
if (messageLength != actualMessageLength)
{
// The underlying socket was closed before we were able to read the whole data.
return;
}
// Read the message and process it.
string message = inputreader.ReadString(actualMessageLength);
OnMessageReceivedEvent(this, message);
}
catch (Exception ex)
{
if (inputreader != null)
OnExceptionOccuredEvent(this, ex);
}
}
}
问题是Bluetooth Stick Reader从不发送连接请求,它只是读取rfid设备ID并通过串行端口发送它。
因此,我能够连接到设备,但是我不知道如何主动侦听或读取传入的数据。
任何帮助将不胜感激。
RFCOMM通信是客户端/服务器模型。 您需要定义用于广播服务的服务器和连接到该服务的客户端。
从您发布的代码中可以看到,它仅包含提供服务的服务器端代码,但没有客户端连接到服务。 仅当客户端连接到服务时,才会触发ConnectionReceived事件。 我编写了一个示例,该示例将RFCOMM服务托管在控制台应用程序中,并在Windows Runtime App中使用了该服务( 代码示例 )。
客户端代码如下:
rfcommServiceInfoCollection = await DeviceInformation.FindAllAsync(
RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush));
var count = rfcommServiceInfoCollection.Count;
Debug.WriteLine("Count of RFCOMM Service: " + count);
if(count > 0)
{
lock (this)
{
streamSocket = new StreamSocket();
}
var defaultSvcInfo = rfcommServiceInfoCollection.FirstOrDefault();
rfcommDeviceService = await RfcommDeviceService.FromIdAsync(defaultSvcInfo.Id);
if(rfcommDeviceService == null)
{
Debug.WriteLine("Rfcomm Device Service is NULL, ID = {0}", defaultSvcInfo.Id);
return;
}
Debug.WriteLine("ConnectionHostName: {0}, ConnectionServiceName: {1}", rfcommDeviceService.ConnectionHostName, rfcommDeviceService.ConnectionServiceName);
await streamSocket.ConnectAsync(rfcommDeviceService.ConnectionHostName, rfcommDeviceService.ConnectionServiceName);
顺便说一句,不要忘记在您的appxmanifest中添加RFCOMM功能。
例如:
<m2:DeviceCapability Name="bluetooth.rfcomm">
<m2:Device Id="any">
<m2:Function Type="name:obexObjectPush" />
</m2:Device>
</m2:DeviceCapability
正如Jeffrey所说的,这是一个客户端/服务器模型,但是在我的情况下,客户端没有任何逻辑,也无法请求任何连接。
谢谢您的样品,它帮了很多忙。
尝试了几件事之后,我得到了一些代码,并且在rfcomm服务中运行并监听了“服务器”:
public async Task ConnectToServiceAsync(string name)
{
lock(this.interlock)
{
readBuffer = String.Empty;
}
DeviceInformation serviceInfo = null;
foreach (var device in devices)
{
if(device.Name == name)
{
serviceInfo = device;
break;
}
}
if (serviceInfo != null)
{
DeviceName = serviceInfo.Name;
this.State = BluetoothConnectionState.Connecting;
try
{
// Initialize the target Bluetooth RFCOMM device service
connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);
rfcommService = await connectService;
if (rfcommService != null)
{
// Create a socket and connect to the target
socket = new StreamSocket();
connectAction = socket.ConnectAsync(rfcommService.ConnectionHostName, rfcommService.ConnectionServiceName, SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
await connectAction;//to make it cancellable
writer = new DataWriter(socket.OutputStream);
reader = new DataReader(socket.InputStream);
State = BluetoothConnectionState.Connected;
Task taskReceive = Task.Run(async () => { ListenForMessagesAsync(socket); });
taskReceive.ConfigureAwait(false);
}
else
OnExceptionOccuredEvent(this, new Exception("Unable to create service.\nMake sure that the 'bluetooth.rfcomm' capability is declared with a function of type 'name:serialPort' in Package.appxmanifest."));
}
catch (TaskCanceledException)
{
this.State = BluetoothConnectionState.Disconnected;
}
catch (Exception ex)
{
this.State = BluetoothConnectionState.Disconnected;
OnExceptionOccuredEvent(this, ex);
}
}
}
和听众
private async Task ListenForMessagesAsync(StreamSocket localsocket)
{
while (socket != null)
{
try
{
string message = String.Empty;
DataReader dataReader = new DataReader(localsocket.InputStream);
dataReader.InputStreamOptions = InputStreamOptions.Partial;
// Read the message and process it.
lock (this.interlock)
{
if (!message.Contains("\r\n"))
readBuffer = readBuffer + message;
else
{
var data = message.Split('\r');
readBuffer = readBuffer + data[0];
}
if (readBuffer.Length == 15)
{
readBuffer = readBuffer.Replace("\r\n", "");
OnMessageReceivedEvent(this, readBuffer);
readBuffer = String.Empty;
}
if (readBuffer.Length > 15 || (readBuffer.Length < 15 && readBuffer.Contains("\r\n")))
readBuffer = String.Empty;
}
}
catch (Exception ex)
{
if (socket != null)
OnExceptionOccuredEvent(this, ex);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.