WebSocket quote Pinnacle in Kotlin (OkHttp)
Risposta: con OkHttp, costruisci una Request verso wss://pinnfeed.io/v1/stream con header x-api-key, chiama newWebSocket, invia un JSON subscribe in onOpen, e rispondi {"type":"pong"} a ogni ping server (ogni 20 s). Frame: welcome, subscribed, parti snapshot, poi delta. Builder (99 €/mese) o Pro.
Gradle#
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("org.json:json:20240303")
}
Client#
import okhttp3.*
import org.json.JSONObject
import java.util.concurrent.TimeUnit
fun main() {
val key = System.getenv("PINNFEED_KEY") ?: error("set PINNFEED_KEY") // ps_live_...
val client = OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS).build()
fun connect(delayMs: Long = 0) {
Thread.sleep(delayMs)
val req = Request.Builder().url("wss://pinnfeed.io/v1/stream").header("x-api-key", key).build()
client.newWebSocket(req, object : WebSocketListener() {
override fun onOpen(ws: WebSocket, response: Response) {
ws.send("""{"type":"subscribe","sports":["soccer"],"markets":["moneyline"],"main":true}""")
}
override fun onMessage(ws: WebSocket, text: String) {
val msg = JSONObject(text)
when (msg.getString("type")) {
"ping" -> ws.send("""{"type":"pong"}""")
"delta" -> {
val changes = msg.getJSONArray("changes")
for (i in 0 until changes.length()) {
val ch = changes.getJSONObject(i)
if (ch.getString("kind") == "market" && ch.getString("op") == "upsert") {
val m = ch.getJSONObject("market")
if (m.optDouble("maxStake", 0.0) >= 100) println("${m.getLong("eventId")} ${m.getJSONArray("outcomes")}")
}
}
}
"error" -> println("error ${msg.optString("code")}: ${msg.optString("message")}")
}
}
override fun onClosed(ws: WebSocket, code: Int, reason: String) {
println("closed $code $reason")
if (code != 4001) connect(2000) // 4001 = key revoked
}
override fun onFailure(ws: WebSocket, t: Throwable, response: Response?) {
println("failure ${response?.code} ${t.message}")
connect(5000)
}
})
}
connect()
}
CTA#
Builder (99 €/mese). Prova 3 giorni; carta richiesta. REST gratis: signup.
Domande frequenti#
Perché Builder?#
/v1/stream richiede Builder o Pro. Free/Hobby ricevono 403 plan_lacks_ws.
Serve un SDK ufficiale?#
No — OkHttp + JSON bastano.
Contenuto educativo per adulti?#
Sì (18+).
Contenuto educativo per maggiorenni (18+): non pronostici né promesse di guadagno. In Italia scommetti solo con operatori autorizzati ADM.