2015-08-22 2 views
1

Я разработки универсального приложения Win8.1/WP8.1 Я в состоянии обнаружить и подключиться к спаренным устройствам Bluetooth (Стик читателей - RFID)Чтение данных из StreamSocketListener на RFCOMM подключения Bluetooth устройство C#

Это, как я подключении

Переменные

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 Стик чтения никогда не посылать запрос на соединение, он просто читать ID устройства и RFID отправляет его через последовательный порт.
Итак, я могу подключиться к устройству, но я не знаю, как активно слушать или читать входящие данные.
Любая помощь будет оценена по достоинству.

ответ

0

Связь RFCOMM - модель клиент/сервер. Вам необходимо определить сервер для трансляции службы и клиента, подключенного к службе.

Как я понял из кода, который вы публикуете, он включает только код на стороне сервера, который предоставляет услугу, но клиент не подключался к сервису. Только когда клиент подключился к службе, событие ConnectionReceived будет запущено. Я написал образец, который размещает службу RFCOMM в консольном приложении и потребляет службу в приложении Windows Runtime до (Code Sample).

код Клиент выглядит следующим образом:

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); 

Кстати, не забудьте добавить возможности RFCOMM в вашем appxmanifest.

Например:

<m2:DeviceCapability Name="bluetooth.rfcomm"> 
    <m2:Device Id="any"> 
    <m2:Function Type="name:obexObjectPush" /> 
    </m2:Device> 
</m2:DeviceCapability 
+0

Привет Джеффри, спасибо за ваше время. что это имеет смысл для модели клиент-сервер –

0

Как сказал Джеффри, это модель клиент/сервер, но в моем случае, если клиент не имеет никакой логики, и не в состоянии запросить какую-либо связь.

Спасибо за ваши образцы, это очень помогло.

Перепробовав несколько вещей, которые я получил код работает, и «сервер» работает и прослушивание в службе 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); 
      } 
     } 
    }