{"id":545507,"date":"2025-02-13T13:48:01","date_gmt":"2025-02-13T12:48:01","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=kotlin&#038;p=545507"},"modified":"2025-02-13T15:34:19","modified_gmt":"2025-02-13T14:34:19","slug":"ktor-3-1-0-release","status":"publish","type":"kotlin","link":"https:\/\/blog.jetbrains.com\/ko\/kotlin\/2025\/02\/ktor-3-1-0-release","title":{"rendered":"Ktor 3.1.0 Release"},"content":{"rendered":"\n<p>Ktor 3.1.0 is here! This is the first minor release of the year, bringing exciting new features, performance improvements, and bug fixes. This release includes improvements to server-sent events (SSE), documentation enhancements, WebAssembly (Wasm) support, dependency injection design updates, and some initial steps toward gRPC integration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">? Get started with Ktor 3.1.0 now!<\/h2>\n\n\n\n<p>Ready to explore Ktor 3.1.0? Start building your next project today with our interactive project generator at <a href=\"https:\/\/kotl.in\/ixiien\" data-type=\"link\" data-id=\"https:\/\/kotl.in\/ixiien\" target=\"_blank\" rel=\"noopener\">start.ktor.io<\/a>. Your feedback and contributions are always welcome!<\/p>\n\n\n\n<p>? <a href=\"https:\/\/ktor.io\/docs\/welcome.html\" target=\"_blank\" rel=\"noopener\">Get Started With Ktor<\/a> | ? Join the Community on <a href=\"https:\/\/www.reddit.com\/r\/ktor\/\" target=\"_blank\" rel=\"noopener\">Reddit<\/a> and <a href=\"https:\/\/surveys.jetbrains.com\/s3\/kotlin-slack-sign-up?_gl=1*1wxglsg*_gcl_au*MTE4MjgxMTg3Mi4xNzM2MjY0ODgy*_ga*MTYyODczMDg5NS4xNzAyMDQyMTMx*_ga_9J976DJZ68*MTczODY3Mjg3Ny4xOTguMS4xNzM4NjczNDI2LjM2LjAuMA..\" target=\"_blank\" rel=\"noopener\">Slack<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Release notes<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Ktor CLI: A new tool to create Ktor projects<\/h2>\n\n\n\n<p>We&#8217;re introducing a new command-line tool designed to simplify the creation of Ktor projects. It provides an easy-to-use interface for generating project templates with your preferred features, reducing boilerplate and setup times.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Ktor CLI Generator Demo\" width=\"500\" height=\"375\" src=\"https:\/\/www.youtube.com\/embed\/mnfRGl7yMqU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Installation<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">MacOS and Linux (with Homebrew <a href=\"https:\/\/brew.sh\/\" target=\"_blank\" rel=\"noopener\">https:\/\/brew.sh\/<\/a>)<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">brew install ktor<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">&#8211; Windows (with <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/package-manager\/winget\/\" target=\"_blank\" rel=\"noopener\">Winget<\/a>):<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">winget install --id=JetBrains.KtorCLI -e<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">How to create a project<\/h3>\n\n\n\n<p>To start a new project, simply run:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">ktor new<\/pre>\n\n\n\n<p>This command opens interactive mode, allowing you to select plugins and configure your project based on the same options available at (<a href=\"https:\/\/kotl.in\/ixiien\" data-type=\"link\" data-id=\"https:\/\/kotl.in\/ixiien\" target=\"_blank\" rel=\"noopener\">start.ktor.io<\/a>).<\/p>\n\n\n\n<p>For the non-interactive mode, run <code>ktor --help<\/code> to see the available options.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Contributing<\/h3>\n\n\n\n<p>Ktor CLI is open source! Share your feedback and contribute at <a href=\"https:\/\/github.com\/ktorio\/ktor-cli\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/ktorio\/ktor-cli<\/a>.<\/p>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-3808\" target=\"_blank\" rel=\"noopener\">KTOR-3808<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">SSE improvements: Serialization, reconnection, heartbeat<\/h2>\n\n\n\n<p>Server-sent events (SSE) support has been enhanced with built-in serialization for both the client and server side. The feature allows clients and servers to handle SSE streams with automatic (de)serialization. Users simply provide a deserialize function to convert incoming data into typed objects as follows:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Client-side SSE with deserialization<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">client.sse({\n\u00a0\u00a0\u00a0\u00a0\u00a0url(\"http:\/\/localhost:8080\/serverSentEvents\")\n\u00a0}, deserialize = { typeInfo, jsonString ->\n\u00a0\u00a0\u00a0\u00a0\u00a0val serializer = Json.serializersModule.serializer(typeInfo.kotlinType!!)\n\u00a0\u00a0\u00a0\u00a0\u00a0Json.decodeFromString(serializer, jsonString)!!\n\u00a0}) {\n\u00a0\u00a0\u00a0\u00a0\u00a0incoming.collect { event: TypedServerSentEvent&lt;String> ->\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0when (event.event) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"customer\" -> {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val customer: Customer? = deserialize&lt;Customer>(event.data)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"product\" -> {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val product: Product? = deserialize&lt;Product>(event.data)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Server-side SSE with serialization<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">routing {\n\u00a0\u00a0\u00a0\u00a0\u00a0sse(\"\/json\", serialize = { typeInfo, it ->\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val serializer = Json.serializersModule.serializer(typeInfo.kotlinType!!)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Json.encodeToString(serializer, it)\n\u00a0\u00a0\u00a0\u00a0\u00a0}) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0send(Customer(0, \"Jet\", \"Brains\"))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0send(Product(0, listOf(100, 200)))\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0}<\/pre>\n\n\n\n<p>These improvements simplify working with structured SSE data in Ktor.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">SSE Heartbeat<\/h3>\n\n\n\n<p>Server-sent events (SSE) now include the ability to specify a heartbeat event to keep the session active. The <code>heartbeat<\/code> will send a specified event at a defined interval as long as the session remains active. This helps maintain the connection during idle periods.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">routing {\n\u00a0\u00a0\u00a0\u00a0sse {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0heartbeat {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0period = 10.seconds\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0event = ServerSentEvent(\"heartbeat\")\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/\u00a0 ...\n\u00a0\u00a0\u00a0\u00a0}\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">SSE reconnect<\/h3>\n\n\n\n<p>Starting from 3.1.0, you can enable the server-sent events (SSE) reconnection feature by setting the <code>maxReconnectionAttempts<\/code> property to a value greater than zero:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">install(SSE) {\n\u00a0\u00a0\u00a0\u00a0maxReconnectionAttempts = 4\n\u00a0\u00a0\u00a0\u00a0reconnectionTime = 2.seconds\n}<\/pre>\n\n\n\n<p>If the connection to the server is lost, the client will wait for the specified <code>reconnectionTime<\/code> before attempting to reconnect, making no more than <code>maxReconnectionAttempts<\/code> attempts to reestablish the connection.<\/p>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-7435\" target=\"_blank\" rel=\"noopener\">KTOR-7435<\/a>, <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-6242\" target=\"_blank\" rel=\"noopener\">KTOR-6242<\/a>, <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-7954\" target=\"_blank\" rel=\"noopener\">KTOR-7954<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Support multipart with HttpClient<\/h2>\n\n\n\n<p>Ktor&#8217;s HttpClient now includes improved support for multipart requests, making it easier to upload files and handle complex request bodies across different engines.<\/p>\n\n\n\n<p>It is now possible to receive <code>MultiPartData<\/code> with the HttpClient:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val response = client.post(\"https:\/\/myserver.com\/multipart\/receive\")\n\nval multipart = response.body&lt;MultiPartData>()\n\nmultipart.forEachPart { part ->\n\u00a0\u00a0\u00a0\u00a0when (part) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0is PartData.FormItem -> {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0println(\"Form item key: \\${part.name}\")\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val value = part.value\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ ...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0is PartData.FileItem -> {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0println(\"file: \\${part.name}\")\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0println(part.originalFileName)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val fileContent: ByteReadChannel = part.provider()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ ...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0part.dispose()\n}<\/pre>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-6632\" target=\"_blank\" rel=\"noopener\">KTOR-6632<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">API and docs improvements process<\/h2>\n\n\n\n<p>We are constantly working on polishing the quality of the API and its associated documentation. We understand that reporting problems may be challenging, so to simplify this process, we introduced the <em>Report a Problem<\/em> link for every API symbol available both in the IDE\u2019s help section and on <a href=\"https:\/\/api.ktor.io\" target=\"_blank\" rel=\"noopener\">api.ktor.io<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1586\" height=\"1178\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/02\/image-17.png\" alt=\"\" class=\"wp-image-545822\"\/><\/figure>\n\n\n\n<p>This button will lead you to the anonymous feedback form (<a href=\"https:\/\/ktor.io\/feedback\/\" target=\"_blank\" rel=\"noopener\">https:\/\/ktor.io\/feedback\/<\/a>), allowing you to provide API-specific feedback or report a bug. Your feedback will be logged as an issue and addressed in future releases.<\/p>\n\n\n\n<p>Documentation is a key part of Ktor, and we&#8217;ve introduced a structured API docs improvement process to ensure better clarity, consistency, and usability for developers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Compression plugin can be disabled for a specific request<\/h2>\n\n\n\n<p>The Compression plugin compresses responses if the client supports it. However, sometimes compression needs to be suppressed (e.g. for proxying or storing compressed content).<\/p>\n\n\n\n<p>Previously, options were available for compression but not for decompression. Now, we\u2019ve added helpers and flags for finer control:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">fun Application.module() {\n\u00a0\u00a0\u00a0\u00a0install(Compression)\n\u00a0\u00a0\u00a0\u00a0routing {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0get(\"\/endpoint-without-compression\") {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Prevent response body compression\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0call.suppressCompression()\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0println(call.isDecompressionSuppressed)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Prevent request body decompression\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0call.suppressDecompression()\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0println(call.isCompressionSuppressed) \/\/ true\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n}<\/pre>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-7679\" target=\"_blank\" rel=\"noopener\">KTOR-7679<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">CIO: Add wasm-js and js targets for the CIO server, client, and network API<\/h2>\n\n\n\n<p>The CIO has been expanded to support wasm-js and js targets for both the server and client side. This makes CIO the first <strong>server-side JavaScript engine<\/strong> for Ktor, enabling the running of Ktor-based servers directly in JavaScript environments.<\/p>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-865\" target=\"_blank\" rel=\"noopener\">KTOR-865<\/a>, <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-7675\" target=\"_blank\" rel=\"noopener\">KTOR-7675<\/a>, <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-6004\" target=\"_blank\" rel=\"noopener\">KTOR-6004<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Further improvements and bug fixes for kotlinx-io integration<\/h2>\n\n\n\n<p>The integration with the kotlinx-io continues to be refined, improving performance, memory usage, and closer interactions across Ktor async io implementations. We have also added a new API extension to convert between kotlinx-io and Ktor and Java io primitives.<\/p>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-7327\" target=\"_blank\" rel=\"noopener\">KTOR-7327<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Add Unix Domain Socket support for native targets<\/h2>\n\n\n\n<p>Ktor now supports Unix Domain Sockets on native targets, enabling inter-process communication (IPC) without relying on TCP.<\/p>\n\n\n\n<p>Here&#8217;s how to create a simple echo server using Unix Domain Sockets:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">fun main() {\n\u00a0\u00a0\u00a0\u00a0val socketPath = \"ktor-echo-test.sock\"\n\u00a0\u00a0\u00a0\u00a0val server = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().bind(UnixSocketAddress(socketPath))\n\n\u00a0\u00a0\u00a0\u00a0println(\"Server is listening on $socketPath\")\n\n\u00a0\u00a0\u00a0\u00a0GlobalScope.launch {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val connection = server.accept()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val input = connection.openReadChannel()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val output = connection.openWriteChannel(autoFlush = true)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val message = input.readUTF8Line()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0println(\"Received: $message\")\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0output.writeStringUtf8(\"Echo: $message\")\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0connection.close()\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0val client = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().connect(UnixSocketAddress(socketPath))\n\u00a0\u00a0\u00a0\u00a0val clientOutput = client.openWriteChannel(autoFlush = true)\n\u00a0\u00a0\u00a0\u00a0clientOutput.writeStringUtf8(\"Hello, Unix Socket!\")\n\n\u00a0\u00a0\u00a0\u00a0val clientInput = client.openReadChannel()\n\u00a0\u00a0\u00a0\u00a0println(clientInput.readUTF8Line())\n\n\u00a0\u00a0\u00a0\u00a0client.close()\n\u00a0\u00a0\u00a0\u00a0server.close()\n\n}<\/pre>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-6960\" target=\"_blank\" rel=\"noopener\">KTOR-6960<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Curl client engine: Static linking, ARM support, WebSockets<\/h2>\n\n\n\n<p>Starting from Ktor 3.1.0, the Curl client engine is statically linked, eliminating the need to install third-party dependencies. This makes it easier to use Curl-based networking. Additionally, ARM architecture support has been added, including for macOS.<\/p>\n\n\n\n<p>Find more information on YouTrack: <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-5199\" target=\"_blank\" rel=\"noopener\">KTOR-5199<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Welcome Ktor Library Improvement Proposals (<a href=\"https:\/\/github.com\/ktorio\/ktor-klip\" target=\"_blank\" rel=\"noopener\">KLIP<\/a>?)<\/h1>\n\n\n\n<p>We\u2019re happy to introduce Ktor Library Improvement Proposals (KLIP) \u2013 an open initiative for the community to propose, discuss, and collaborate on new features and improvements for Ktor. The KLIP process is designed to make Ktor\u2019s evolution transparent and community-driven. The KLIP repository is open for contributions, and we welcome everyone to participate in discussions or submit new proposals. Approved KLIPs are merged into the repository and will be implemented in the framework by the team.<\/p>\n\n\n\n<p>The first ? dependency injection is available for review and feedback: <a href=\"https:\/\/github.com\/ktorio\/ktor-klip\/pull\/1\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/ktorio\/ktor-klip\/pull\/1<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Looking forward to gRPC support with kotlinx-rpc<\/h1>\n\n\n\n<p>The basic support of the gRPC has been added to kotlinx-rpc 0.5.0: <a href=\"https:\/\/kotlin.github.io\/kotlinx-rpc\/grpc-configuration.html#dependencies-configuration\" target=\"_blank\" rel=\"noopener\">https:\/\/kotlin.github.io\/kotlinx-rpc\/grpc-configuration.html#dependencies-configuration<\/a>. This moves the highly requested <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KTOR-1501\" target=\"_blank\" rel=\"noopener\">KTOR-1501<\/a> proposal forward. We\u2019re planning further Ktor integration with gRPC, along with a plugin for <a href=\"https:\/\/kotl.in\/ixiien\" data-type=\"link\" data-id=\"https:\/\/kotl.in\/ixiien\" target=\"_blank\" rel=\"noopener\">start.ktor.io<\/a> in future releases. This will help to simplify the setup and use of gRPC in Ktor applications.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">MCP: Exposing and consuming APIs for LLMs<\/h1>\n\n\n\n<p>In preparation for Ktor 3.1.0, we&#8217;ve been helping to build the MCP Kotlin SDK (<a href=\"https:\/\/github.com\/modelcontextprotocol\/kotlin-sdk\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/modelcontextprotocol\/kotlin-sdk<\/a>). This lightweight SDK enables integration between your applications and large language models (LLMs), allowing you to expose your APIs to language models and agents or build clients connecting multiple applications with LLMs. The library is already published on MavenCentral.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">? Thank you!<\/h1>\n\n\n\n<p>We want to say thank you to everyone for all the contributions and feedback you provide!<\/p>\n\n\n\n<p>We especially want to mention the following active contributors: <a href=\"https:\/\/github.com\/anton-erofeev\" target=\"_blank\" rel=\"noopener\">anton-erofeev<\/a>, <a href=\"https:\/\/github.com\/FredrikMeyer\" target=\"_blank\" rel=\"noopener\">FredrikMeyer<\/a>, <a href=\"https:\/\/github.com\/IRus\" target=\"_blank\" rel=\"noopener\">IRus<\/a>, <a href=\"https:\/\/github.com\/whyoleg\" target=\"_blank\" rel=\"noopener\">whyoleg<\/a>, <a href=\"https:\/\/github.com\/SIMULATAN\" target=\"_blank\" rel=\"noopener\">SIMULATAN<\/a>, <a href=\"https:\/\/github.com\/Thomas-Vos\" target=\"_blank\" rel=\"noopener\">Thomas-Vos<\/a>, and <a href=\"https:\/\/github.com\/adriandieter\" target=\"_blank\" rel=\"noopener\">adriandieter<\/a>.<\/p>\n\n\n\n<p>Start building your next project with <a href=\"https:\/\/kotl.in\/ixiien\" data-type=\"link\" data-id=\"https:\/\/kotl.in\/ixiien\" target=\"_blank\" rel=\"noopener\">start.ktor.io<\/a>. Your feedback and contributions are always welcome!<\/p>\n\n\n\n<p>? <a href=\"https:\/\/ktor.io\/docs\/welcome.html\" target=\"_blank\" rel=\"noopener\">Get Started With Ktor<\/a> | ? Join the Community on <a href=\"https:\/\/www.reddit.com\/r\/ktor\/\" target=\"_blank\" rel=\"noopener\">Reddit<\/a> and <a href=\"https:\/\/surveys.jetbrains.com\/s3\/kotlin-slack-sign-up?_gl=1*1wxglsg*_gcl_au*MTE4MjgxMTg3Mi4xNzM2MjY0ODgy*_ga*MTYyODczMDg5NS4xNzAyMDQyMTMx*_ga_9J976DJZ68*MTczODY3Mjg3Ny4xOTguMS4xNzM4NjczNDI2LjM2LjAuMA..\" target=\"_blank\" rel=\"noopener\">Slack<\/a><\/p>\n","protected":false},"author":1171,"featured_media":545685,"comment_status":"closed","ping_status":"closed","template":"","categories":[4897,89],"tags":[4292,477],"cross-post-tag":[6634],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/kotlin\/545507"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/kotlin"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/types\/kotlin"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/users\/1171"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/comments?post=545507"}],"version-history":[{"count":9,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/kotlin\/545507\/revisions"}],"predecessor-version":[{"id":545839,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/kotlin\/545507\/revisions\/545839"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/media\/545685"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/media?parent=545507"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/categories?post=545507"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/tags?post=545507"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/cross-post-tag?post=545507"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}