Skip to content

Latest commit

 

History

History
258 lines (199 loc) · 11.2 KB

signalr-quickstart-azure-functions-java.md

File metadata and controls

258 lines (199 loc) · 11.2 KB
titledescriptionauthorms.authorms.datems.topicms.servicems.devlangms.custom
Use Java to create a chat room with Azure Functions and SignalR Service
A quickstart for using Azure SignalR Service and Azure Functions to create an App showing GitHub star count using Java.
vicancy
lianwei
04/04/2022
quickstart
azure-signalr-service
java
devx-track-java, mode-api, devx-track-extended-java

Quickstart: Use Java to create an App showing GitHub star count with Azure Functions and SignalR Service

In this article, you'll use Azure SignalR Service, Azure Functions, and Java to build a serverless application to broadcast messages to clients.

Note

The code in this article is available on GitHub.

[!INCLUDE Connection string security]

Prerequisites

  • A code editor, such as Visual Studio Code

  • An Azure account with an active subscription. If you don't already have an account, create an account for free.

  • Azure Functions Core Tools. Used to run Azure Function apps locally.

    • The required SignalR Service bindings in Java are only supported in Azure Function Core Tools version 2.4.419 (host version 2.0.12332) or above.
    • To install extensions, Azure Functions Core Tools requires the .NET Core SDK installed. However, no knowledge of .NET is required to build Java Azure Function apps.
  • Java Developer Kit, version 11

  • Apache Maven, version 3.0 or above.

This quickstart can be run on macOS, Windows, or Linux.

Create an Azure SignalR Service instance

[!INCLUDE Create instance]

Configure and run the Azure Function app

Make sure you have Azure Function Core Tools, Java (version 11 in the sample), and Maven installed.

  1. Initialize the project using Maven:

    mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=11

    Maven asks you for values needed to finish generating the project. Provide the following values:

    PromptValueDescription
    groupIdcom.signalrA value that uniquely identifies your project across all projects, following the package naming rules for Java.
    artifactIdjavaA value that is the name of the jar, without a version number.
    version1.0-SNAPSHOTChoose the default value.
    packagecom.signalrA value that is the Java package for the generated function code. Use the default.
  2. Go to the folder src/main/java/com/signalr and copy the following code to Function.java:

    packagecom.signalr; importcom.google.gson.Gson; importcom.microsoft.azure.functions.ExecutionContext; importcom.microsoft.azure.functions.HttpMethod; importcom.microsoft.azure.functions.HttpRequestMessage; importcom.microsoft.azure.functions.HttpResponseMessage; importcom.microsoft.azure.functions.HttpStatus; importcom.microsoft.azure.functions.annotation.AuthorizationLevel; importcom.microsoft.azure.functions.annotation.FunctionName; importcom.microsoft.azure.functions.annotation.HttpTrigger; importcom.microsoft.azure.functions.annotation.TimerTrigger; importcom.microsoft.azure.functions.signalr.*; importcom.microsoft.azure.functions.signalr.annotation.*; importorg.apache.commons.io.IOUtils; importjava.io.IOException; importjava.io.InputStream; importjava.net.URI; importjava.net.http.HttpClient; importjava.net.http.HttpRequest; importjava.net.http.HttpResponse; importjava.net.http.HttpResponse.BodyHandlers; importjava.nio.charset.StandardCharsets; importjava.util.Optional; publicclassFunction { privatestaticStringEtag = ""; privatestaticStringStarCount; @FunctionName("index") publicHttpResponseMessagerun( @HttpTrigger( name = "req", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.ANONYMOUS)HttpRequestMessage<Optional<String>> request, finalExecutionContextcontext) throwsIOException { InputStreaminputStream = getClass().getClassLoader().getResourceAsStream("content/index.html"); Stringtext = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name()); returnrequest.createResponseBuilder(HttpStatus.OK).header("Content-Type", "text/html").body(text).build(); } @FunctionName("negotiate") publicSignalRConnectionInfonegotiate( @HttpTrigger( name = "req", methods = { HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req, @SignalRConnectionInfoInput( name = "connectionInfo", hubName = "serverless") SignalRConnectionInfoconnectionInfo) { returnconnectionInfo; } @FunctionName("broadcast") @SignalROutput(name = "$return", hubName = "serverless") publicSignalRMessagebroadcast( @TimerTrigger(name = "timeTrigger", schedule = "*/5 * * * * *") StringtimerInfo) throwsIOException, InterruptedException { HttpClientclient = HttpClient.newHttpClient(); HttpRequestreq = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/repos/azure/azure-signalr")).header("User-Agent", "serverless").header("If-None-Match", Etag).build(); HttpResponse<String> res = client.send(req, BodyHandlers.ofString()); if (res.headers().firstValue("Etag").isPresent()) { Etag = res.headers().firstValue("Etag").get(); } if (res.statusCode() == 200) { Gsongson = newGson(); GitResultresult = gson.fromJson(res.body(), GitResult.class); StarCount = result.stargazers_count; } returnnewSignalRMessage("newMessage", "Current start count of https://github.com/Azure/azure-signalr is:".concat(StarCount)); } classGitResult { publicStringstargazers_count; } }
  3. Some dependencies need to be added. Open pom.xml and add the following dependencies used in the code:

    <dependency> <groupId>com.microsoft.azure.functions</groupId> <artifactId>azure-functions-java-library-signalr</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.7</version> </dependency>
  4. The client interface for this sample is a web page. We read HTML content from content/index.html in the index function, and then create a new file content/index.html in the resources directory. Your directory tree should look like this:

     | - src | | - main | | | - java | | | | - com | | | | | - signalr | | | | | | - Function.java | | | - resources | | | | - content | | | | | - index.html | - pom.xml | - host.json | - local.settings.json 
  5. Open index.html and copy the following content:

    <html><body><h1>Azure SignalR Serverless Sample</h1><divid="messages"></div><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.min.js"></script><script>letmessages=document.querySelector('#messages');constapiBaseUrl=window.location.origin;constconnection=newsignalR.HubConnectionBuilder().withUrl(apiBaseUrl+'/api').configureLogging(signalR.LogLevel.Information).build();connection.on('newMessage',(message)=>{document.getElementById("messages").innerHTML=message;});connection.start().catch(console.error);</script></body></html>
  6. Azure Functions requires a storage account to work. You can install and run the Azure Storage Emulator.

  7. You're almost done now. The last step is to set a connection string of the SignalR Service to Azure Function settings.

    1. Search for the Azure SignalR instance you deployed earlier using the Search box in Azure portal. Select the instance to open it.

      Search for the SignalR Service instance

    2. Select Keys to view the connection strings for the SignalR Service instance.

      Screenshot that highlights the primary connection string.

    3. Copy the primary connection string, and then run the following command.

      [!INCLUDE Connection string security comment]

      func settings add AzureSignalRConnectionString "<signalr-connection-string>"# Also we need to set AzureWebJobsStorage as Azure Function's requirement func settings add AzureWebJobsStorage "UseDevelopmentStorage=true"
  8. Run the Azure Function in local:

    mvn clean package mvn azure-functions:run

    After Azure Function is running locally, go to http://localhost:7071/api/index and you'll see the current star count. If you star or "unstar" in the GitHub, you'll get a star count refreshing every few seconds.

[!INCLUDE Cleanup]

Having issues? Try the troubleshooting guide or let us know.

Next steps

In this quickstart, you built and ran a real-time serverless application in the local host. Next, learn more about how to bi-directional communicating between clients and Azure Function with SignalR Service.

[!div class="nextstepaction"] SignalR Service bindings for Azure Functions

[!div class="nextstepaction"] Bi-directional communicating in Serverless

[!div class="nextstepaction"] Create your first function with Java and Maven

close