---
title: "Using the socketR R6 Interface"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Using the socketR R6 Interface}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

The `Socket` class provides a method-oriented interface over the functional
socket API. This example creates a TCP server and client on the IPv4 loopback
interface, exchanges a message, and closes every object explicitly.

```{r r6-tcp, eval=FALSE}
library(socketR)

server <- Socket$new("inet", "stream")
client <- Socket$new("inet", "stream")
peer <- NULL

on.exit({
  if (!is.null(peer)) peer$close()
  client$close()
  server$close()
}, add = TRUE)

server$set_option("socket", "reuseaddr", TRUE, "logical")
server$bind("127.0.0.1", 0L)
server$listen()

client$connect("127.0.0.1", server$local_name()$port)
peer <- server$accept()

client$send("hello from the R6 API")
peer$poll("read", timeout_ms = 1000L)
rawToChar(peer$receive(n = 21L))
```

Options and socket metadata are available as methods on the same object:

```{r r6-options, eval=FALSE}
client$info()
client$fd()
client$set_blocking(FALSE)
client$get_option("socket", "keepalive", "logical")
client$set_options(list(
  list(level = "socket", option = "keepalive",
       value = TRUE, type = "logical"),
  list(level = "tcp", option = "nodelay",
       value = TRUE, type = "logical")
))
```

For APIs that expect a base R connection, use `as_connection()`. The adapter
can be passed to `writeBin()`, `readBin()`, `readLines()`, and `writeLines()`;
closing the adapter does not close the underlying `Socket`, so close both
objects explicitly.

```{r r6-connection, eval=FALSE}
connection <- client$as_connection()
writeBin(charToRaw("bytes through an R connection"), connection)
close(connection)
client$close()
```

