Hello,
I have a weird problem. I'm using Node.js & Express to serve a Server-Sent-Events endpoint. It does something like this:
router.get("/", async (request, response, next) => {
response.writeHead(200, {
"Content-Type": "text/event-stream",
Connection: "keep-alive",
"Cache-Control": "no-cache",
});
// save response object, use it later to send events
request.on("close", () => {
console.log(`${clientId} Connection closed`);
delete clients[clientId];
});
I have an endpoint to give me the number of connected clients. Locally, as soon as I disconnect from the endpoint the "close" event is called and the client is removed.
On Azure App Service, for some reason, the network connections are never closed. I tried executing "lsof" on the containers, and the connections are really there and are not closed for hours. Anyone got any idea why this could be? I suspect the app-service load balancer is responsible for this.
Here are some of the settings:
{
"type": "Microsoft.Web/sites",
"kind": "app,linux,container",
"properties": {
"state": "Running",
"owner": null,
"usageState": 0,
"enabled": true,
"adminEnabled": true,
"siteProperties": {
"metadata": null,
"properties": [
{
"name": "LinuxFxVersion",
"value": "DOCKER|..."
},
{
"name": "WindowsFxVersion",
"value": null
}
],
"appSettings": null
},
"availabilityState": 0,
"sslCertificates": null,
"csrs": [],
"cers": null,
"siteMode": null,
"computeMode": null,
"serverFarm": null,
"reserved": true,
"isXenon": false,
"hyperV": false,
"lastModifiedTimeUtc": "2023-08-11T11:53:53.9866667",
"storageRecoveryDefaultState": "Running",
"contentAvailabilityState": 0,
"runtimeAvailabilityState": 0,
"dnsConfiguration": {},
"vnetRouteAllEnabled": false,
"containerAllocationSubnet": null,
"useContainerLocalhostBindings": null,
"vnetImagePullEnabled": false,
"vnetContentShareEnabled": false,
"siteConfig": {
"numberOfWorkers": 1,
"defaultDocuments": null,
"netFrameworkVersion": null,
"phpVersion": null,
"pythonVersion": null,
"nodeVersion": null,
"powerShellVersion": null,
"linuxFxVersion": "DOCKER|...",
"windowsFxVersion": null,
"windowsConfiguredStacks": null,
"requestTracingEnabled": null,
"remoteDebuggingEnabled": null,
"remoteDebuggingVersion": null,
"httpLoggingEnabled": null,
"azureMonitorLogCategories": null,
"acrUseManagedIdentityCreds": true,
"acrUserManagedIdentityID": null,
"logsDirectorySizeLimit": null,
"detailedErrorLoggingEnabled": null,
"publishingUsername": null,
"publishingPassword": null,
"appSettings": null,
"metadata": null,
"connectionStrings": null,
"machineKey": null,
"handlerMappings": null,
"documentRoot": null,
"scmType": null,
"use32BitWorkerProcess": null,
"webSocketsEnabled": null,
"alwaysOn": true,
"javaVersion": null,
"javaContainer": null,
"javaContainerVersion": null,
"appCommandLine": null,
"managedPipelineMode": null,
"virtualApplications": null,
"winAuthAdminState": null,
"winAuthTenantState": null,
"customAppPoolIdentityAdminState": null,
"customAppPoolIdentityTenantState": null,
"runtimeADUser": null,
"runtimeADUserPassword": null,
"loadBalancing": null,
"routingRules": null,
"experiments": null,
"limits": null,
"autoHealEnabled": null,
"autoHealRules": null,
"tracingOptions": null,
"vnetName": null,
"vnetRouteAllEnabled": null,
"vnetPrivatePortsCount": null,
"publicNetworkAccess": null,
"cors": null,
"push": null,
"apiDefinition": null,
"apiManagementConfig": null,
"autoSwapSlotName": null,
"localMySqlEnabled": null,
"managedServiceIdentityId": null,
"xManagedServiceIdentityId": null,
"keyVaultReferenceIdentity": null,
"ipSecurityRestrictions": null,
"ipSecurityRestrictionsDefaultAction": null,
"scmIpSecurityRestrictions": null,
"scmIpSecurityRestrictionsDefaultAction": null,
"scmIpSecurityRestrictionsUseMain": null,
"http20Enabled": false,
"minTlsVersion": null,
"minTlsCipherSuite": null,
"supportedTlsCipherSuites": null,
"scmMinTlsVersion": null,
"ftpsState": null,
"preWarmedInstanceCount": null,
"functionAppScaleLimit": 0,
"elasticWebAppScaleLimit": null,
"healthCheckPath": null,
"fileChangeAuditEnabled": null,
"functionsRuntimeScaleMonitoringEnabled": null,
"websiteTimeZone": null,
"minimumElasticInstanceCount": 0,
"azureStorageAccounts": null,
"http20ProxyFlag": null,
"sitePort": null,
"antivirusScanEnabled": null,
"storageType": null
},
"slotName": null,
"trafficManagerHostNames": null,
"sku": "Basic",
"scmSiteAlsoStopped": false,
"targetSwapSlot": null,
"hostingEnvironment": null,
"hostingEnvironmentProfile": null,
"clientAffinityEnabled": false,
"clientCertEnabled": false,
"clientCertMode": 0,
"clientCertExclusionPaths": null,
"hostNamesDisabled": false,
"vnetBackupRestoreEnabled": false,
"domainVerificationIdentifiers": null,
"kind": "app,linux,container",
"managedEnvironmentId": null,
"containerSize": 0,
"dailyMemoryTimeQuota": 0,
"suspendedTill": null,
"siteDisabledReason": 0,
"functionExecutionUnitsCache": null,
"maxNumberOfWorkers": null,
"cloningInfo": null,
"hostingEnvironmentId": null,
"slotSwapStatus": null,
"httpsOnly": true,
"endToEndEncryptionEnabled": false,
"redundancyMode": 0,
"inProgressOperationId": null,
"geoDistributions": null,
"privateEndpointConnections": [],
"publicNetworkAccess": null,
"buildVersion": null,
"targetBuildVersion": null,
"migrationState": null,
"eligibleLogCategories": "AppServiceAppLogs,AppServiceAuditLogs,AppServiceConsoleLogs,AppServiceHTTPLogs,AppServiceIPSecAuditLogs,AppServicePlatformLogs,ScanLogs",
"inFlightFeatures": [],
"storageAccountRequired": false,
"virtualNetworkSubnetId": null,
"keyVaultReferenceIdentity": "SystemAssigned",
"defaultHostNameScope": 0,
"privateLinkIdentifiers": null
},
}
The lsof
connections look like this:
{
"fd": 27,
"type": "IP",
"access": "u",
"lock": " ",
"name": "169.254.129.2:8080->169.254.129.4:36050",
"protocol": "TCP",
"version": 6,
"from": {
"address": "169.254.129.2",
"port": 8080
},
"to": {
"address": "169.254.129.4",
"port": 36050
}
}