param( [int] $Port = 7788, [string] $Log = "$PSScriptRoot\sc_link.log" ) function Say($msg) { for ($i = 0; $i -lt 5; $i++) { try { "$msg" | Out-File -FilePath $Log -Append -Encoding utf8; return } catch { Start-Sleep -Milliseconds 100 } } } "" | Out-File -FilePath $Log -Encoding utf8 Say "[link-sc] starting on 127.0.0.1:$Port" $listener = New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Loopback, $Port) $listener.Server.SetSocketOption('Socket', 'ReuseAddress', $true) $bound = $false for ($i = 0; $i -lt 30 -and -not $bound; $i++) { try { $listener.Start(); $bound = $true } catch { Start-Sleep -Seconds 1 } } if (-not $bound) { Say "[link-sc] could not bind"; exit 1 } Say "[link-sc] listening" $client = $listener.AcceptTcpClient() Say "[link-sc] === shard connected ===" $stream = $client.GetStream() $reader = New-Object System.IO.StreamReader($stream) $writer = New-Object System.IO.StreamWriter($stream) $writer.AutoFlush = $true $deadline = (Get-Date).AddSeconds(20) $confirmed = $false while ((Get-Date) -lt $deadline) { if ($stream.DataAvailable) { $line = $reader.ReadLine() if ($null -eq $line) { break } Say "[link-sc] <- $line" # When the shard emits a link.request, extract the code and confirm it. if (-not $confirmed -and $line -match '"kind":"link\.request"') { if ($line -match '"code":"([^"]+)"') { $code = $Matches[1] $confirm = '{"kind":"link.confirm","code":"' + $code + '","websiteUserId":"web-9931"}' $writer.WriteLine($confirm) Say "[link-sc] -> $confirm" $confirmed = $true } } } else { Start-Sleep -Milliseconds 100 } } # Second exchange: send a bad confirm to prove the error path. $writer.WriteLine('{"kind":"link.confirm","code":"BADCOD","websiteUserId":"web-0000"}') Say '[link-sc] -> {"kind":"link.confirm","code":"BADCOD","websiteUserId":"web-0000"}' $t = (Get-Date).AddSeconds(3) while ((Get-Date) -lt $t) { if ($stream.DataAvailable) { $l = $reader.ReadLine(); if ($l) { Say "[link-sc] <- $l" } } else { Start-Sleep -Milliseconds 100 } } Say "[link-sc] done" $client.Close(); $listener.Stop()