从RFComm蓝牙连接设备上的StreamSocketListener读取数据



我正在开发一个通用应用程序Win8.1/WP8.1我能够发现并连接到配对的蓝牙设备(棒阅读器- 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);
            }
        }
    }

问题是蓝牙棒阅读器从不发送连接请求,它只是读取rfid设备ID并通过串行端口发送。
所以,我能够连接到设备,但我不知道如何积极地收听或读取传入的数据。

RFCOMM通信是Client/Server模式。您需要定义一个服务器来广播该服务,并定义一个连接到该服务的客户端。

正如我从你发布的代码中看到的,它只包括提供服务的服务器端代码,但没有客户端连接到服务。只有当客户端连接到服务时,ConnectionReceived事件才会被触发。我写了一个示例,在控制台应用程序中托管RFCOMM服务,并在Windows运行时应用程序中使用该服务(代码示例)。

客户端代码如下:

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("rn"))
                        readBuffer = readBuffer + message;
                    else
                    {
                        var data = message.Split('r');
                        readBuffer = readBuffer + data[0];
                    }
                    if (readBuffer.Length == 15)
                    {
                        readBuffer = readBuffer.Replace("rn", "");
                        OnMessageReceivedEvent(this, readBuffer);
                        readBuffer = String.Empty;
                    }
                    if (readBuffer.Length > 15 || (readBuffer.Length < 15 && readBuffer.Contains("rn")))
                        readBuffer = String.Empty;
                }

            }
            catch (Exception ex)
            {
                if (socket != null)
                    OnExceptionOccuredEvent(this, ex);
            }
        }
    }

相关内容

  • 没有找到相关文章

最新更新