|
| 1 | +<?xml version="1.0" encoding="utf-8"?> |
| 2 | +<topic id="3ab7deee-1a9a-4d77-9fc4-14343f3bd1ca" revisionNumber="1"> |
| 3 | + <developerConceptualDocument |
| 4 | + xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" |
| 5 | + xmlns:xlink="http://www.w3.org/1999/xlink"> |
| 6 | + |
| 7 | + <!-- |
| 8 | + <summary> |
| 9 | + <para>Optional summary abstract</para> |
| 10 | + </summary> |
| 11 | + --> |
| 12 | + |
| 13 | + <introduction> |
| 14 | + <!-- Uncomment this to generate an outline of the section and sub-section |
| 15 | + titles. Specify a numeric value as the inner text to limit it to |
| 16 | + a specific number of sub-topics when creating the outline. Specify |
| 17 | + zero (0) to limit it to top-level sections only. |
| 18 | + <autoOutline /> --> |
| 19 | + |
| 20 | + <para> |
| 21 | + This example consists of three projects. AntGrpcShared is a class library providing a gRPC client/server to be consumed by the other |
| 22 | + projects. AntGrpcServr is a server console application that provides services to connect to and communicate with an ANT USB stick. |
| 23 | + The MauiAntClientApp is a .NET MAUI project and gRPC client that is used to demonstrate Windows/Android applications that work with the |
| 24 | + remote server application on a local subnet. <legacyBold>I have not tested the other platforms supported by .NET MAUI.</legacyBold> |
| 25 | + </para> |
| 26 | + </introduction> |
| 27 | + |
| 28 | + <!-- Add one or more top-level section elements. These are collapsible. |
| 29 | + If using <autoOutline />, add an address attribute to identify it |
| 30 | + and specify a title so that it can be jumped to with a hyperlink. --> |
| 31 | + <section address="Section1"> |
| 32 | + <title>The MAUI Example Projects</title> |
| 33 | + <content> |
| 34 | + <!-- Uncomment this to create a sub-section outline |
| 35 | + <autoOutline /> --> |
| 36 | + <para>A brief overview of the projects in this example.</para> |
| 37 | + </content> |
| 38 | + <!-- If a section contains a sections element, its content creates |
| 39 | + sub-sections. These are not collapsible. --> |
| 40 | + <sections> |
| 41 | + <section address="SubSection1"> |
| 42 | + <title>AntGrpcShared</title> |
| 43 | + <content> |
| 44 | + <para> |
| 45 | + This class library is configured as a gRPC client/server library. The .proto files define the messages and data exchanged |
| 46 | + between client and server implementations. |
| 47 | + </para> |
| 48 | + </content> |
| 49 | + </section> |
| 50 | + <section address="SubSection2"> |
| 51 | + <title>AntGrpcServer</title> |
| 52 | + <content> |
| 53 | + <para> |
| 54 | + The server is a console application that runs on the host PC that has an ANT USB stick connected to it. Three services are |
| 55 | + provided. |
| 56 | + </para> |
| 57 | + <para> |
| 58 | + The DiscoveryService replies to clients over a UDP multicast port on the local subnet. This allows clients to obtain |
| 59 | + the URI of the server and connect to the gRPC channel. Think of it as a poor man's service discovery protocol. No authentication |
| 60 | + or validation is performed. |
| 61 | + </para> |
| 62 | + <para> |
| 63 | + The AntRadioService provides methods to get information about the connected ANT USB stick, intialize for continuous scan mode, |
| 64 | + and get channels to communicate with ANT devices via the AntChannelService. |
| 65 | + </para> |
| 66 | + <para> |
| 67 | + The AntChannelService has a method to subscribe to a gRPC stream of ANT messages when the ANT USB stick has been initialized |
| 68 | + for continuous scan mode. The remaining gRPC/ANT radio channels are used to send extended acknowledged messages to individual |
| 69 | + ANT devices. |
| 70 | + </para> |
| 71 | + </content> |
| 72 | + </section> |
| 73 | + <section address="SubSection3"> |
| 74 | + <title>MauiAntClientApp</title> |
| 75 | + <content> |
| 76 | + <para> |
| 77 | + The client app is the consumer of the client services provided by AntGrpcShared project. The server URI is first obtained via |
| 78 | + a UDP mulicast message, a gRPC connection to the server is established, and then requests to initialize and communicate with the |
| 79 | + remote ANT USB stick are invoked. |
| 80 | + </para> |
| 81 | + </content> |
| 82 | + </section> |
| 83 | + </sections> |
| 84 | + </section> |
| 85 | + <section address="Section2"> |
| 86 | + <title>How It Works</title> |
| 87 | + <content> |
| 88 | + <para> |
| 89 | + UDP multicast is used for service discovery and https is used for communication between client and server. The multicast discovery |
| 90 | + is invoked first to obtain the server URI, then the server gRPC channel (this is NOT an ANT channel) is connected to using the |
| 91 | + IP address obtained from the reply to the UDP message. I'm assuming the server and client app are on the same local subnet. |
| 92 | + </para> |
| 93 | + <para> |
| 94 | + The UDP multicast endpoint is 239.55.43.6:55437. This is an arbitrary assignment in the multicast address range. You are certainly |
| 95 | + welcome to select your own address and port. The message sent/received is not relevant in this example, we're just interested in |
| 96 | + the server IP address in the received message. This is used in the next step to form the URI to connect to the gRPC server channel. |
| 97 | + </para> |
| 98 | + <para> |
| 99 | + The client then connects to the gRPC server. The URI is constructed from the server IP address and the arbitrary port number |
| 100 | + created when the AntGrpcServer project was created. The AntGrpcServer launchSettings.json file has the port number. Two protocols |
| 101 | + are defined in launchSettings.json; I'm using the https port number. Once the client is connected to the server the client initializes |
| 102 | + continuous scan mode. The client then subscribes to streaming messages from ANT channel 0 and the client app is up and running. |
| 103 | + </para> |
| 104 | + </content> |
| 105 | + </section> |
| 106 | + <relatedTopics> |
| 107 | + <!-- One or more of the following: |
| 108 | + - A local link |
| 109 | + - An external link |
| 110 | + - A code entity reference |
| 111 | +
|
| 112 | + <link xlink:href="Other Topic's ID"/> |
| 113 | + <link xlink:href="Other Topic's ID">Link inner text</link> |
| 114 | +
|
| 115 | + <externalLink> |
| 116 | + <linkText>Link text</linkText> |
| 117 | + <linkAlternateText>Optional alternate link text</linkAlternateText> |
| 118 | + <linkUri>URI</linkUri> |
| 119 | + </externalLink> |
| 120 | +
|
| 121 | + <codeEntityReference>API member ID</codeEntityReference> |
| 122 | +
|
| 123 | + Examples: |
| 124 | +
|
| 125 | + <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8270" /> |
| 126 | + <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link> |
| 127 | +
|
| 128 | + <externalLink> |
| 129 | + <linkText>SHFB on GitHub</linkText> |
| 130 | + <linkAlternateText>Go to GitHub</linkAlternateText> |
| 131 | + <linkUri>https://GitHub.com/EWSoftware/SHFB</linkUri> |
| 132 | + </externalLink> |
| 133 | +
|
| 134 | + <codeEntityReference>T:TestDoc.TestClass</codeEntityReference> |
| 135 | + <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference> |
| 136 | + <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference> |
| 137 | + <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference> |
| 138 | + <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference> |
| 139 | + <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference> |
| 140 | + <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference> |
| 141 | + --> |
| 142 | + </relatedTopics> |
| 143 | + </developerConceptualDocument> |
| 144 | +</topic> |
0 commit comments