チュートリアル · Kotlin · WebSocket
Kotlin(OkHttp)でピナクルオッズWebSocket
回答: OkHttpで wss://pinnfeed.io/v1/stream へ x-api-key 付き Request を作り、newWebSocket を呼び、onOpen で JSON subscribe を送り、サーバーの ping(20秒ごと)に {"type":"pong"} で返します。フレームは welcome、subscribed、snapshot 分割、その後 delta。Builder(99€/月)または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€/月)。3日間トライアル、カード必須。無料REST:signup。
よくある質問#
なぜBuilder?#
/v1/stream はBuilderまたはProが必要。Free/Hobbyは 403 plan_lacks_ws。
公式SDKは必要?#
不要。OkHttp + JSONで十分です。
成人向けの教育コンテンツですか?#
はい(18+)。
18歳以上の方を対象とした教育目的のコンテンツです。予想や利益の約束ではありません。日本では刑法により賭博は原則として禁止されています。