در Live API، یک جلسه به یک اتصال دائمی اشاره دارد که در آن ورودی و خروجی به طور مداوم از طریق یک اتصال پخش میشوند (در مورد نحوه عملکرد آن بیشتر بخوانید). این طراحی منحصربهفرد جلسه تأخیر کم را امکانپذیر میکند و از ویژگیهای منحصربهفرد پشتیبانی میکند، اما میتواند چالشهایی مانند محدودیتهای زمانی جلسه و خاتمه زودهنگام را نیز ایجاد کند. این راهنما استراتژیهایی را برای غلبه بر چالشهای مدیریت جلسه که ممکن است هنگام استفاده از Live API ایجاد شود، پوشش میدهد.
طول عمر جلسه
بدون فشرده سازی، جلسات فقط صوتی به 15 دقیقه و جلسات صوتی و تصویری به 2 دقیقه محدود می شود. فراتر از این محدودیتها، جلسه (و در نتیجه، اتصال) خاتمه مییابد، اما میتوانید از فشردهسازی پنجره زمینه برای گسترش جلسات به مدت نامحدود استفاده کنید.
طول عمر اتصال نیز به حدود 10 دقیقه محدود شده است. هنگامی که اتصال قطع می شود، جلسه نیز خاتمه می یابد. در این مورد، میتوانید یک جلسه را برای فعال ماندن در چندین اتصال با استفاده از از سرگیری جلسه پیکربندی کنید. همچنین قبل از پایان اتصال یک پیام GoAway دریافت خواهید کرد که به شما امکان می دهد اقدامات بیشتری انجام دهید.
فشرده سازی پنجره زمینه
برای فعال کردن جلسات طولانی تر و جلوگیری از قطع ناگهانی اتصال، می توانید فشرده سازی پنجره زمینه را با تنظیم فیلد contextWindowCompression به عنوان بخشی از پیکربندی جلسه فعال کنید.
برای جلوگیری از خاتمه جلسه هنگامی که سرور به طور دوره ای اتصال WebSocket را بازنشانی می کند، فیلد sessionResumption را در پیکربندی راه اندازی پیکربندی کنید.
ژتون های Resumption به مدت 2 ساعت پس از پایان آخرین جلسات معتبر هستند.
پایتون
importasynciofromgoogleimportgenaifromgoogle.genaiimporttypesclient=genai.Client()model="gemini-live-2.5-flash-preview"asyncdefmain():print(f"Connecting to the service with handle {previous_session_handle}...")asyncwithclient.aio.live.connect(model=model,config=types.LiveConnectConfig(response_modalities=["AUDIO"],session_resumption=types.SessionResumptionConfig(# The handle of the session to resume is passed here,# or else None to start a new session.handle=previous_session_handle),),)assession:whileTrue:awaitsession.send_client_content(turns=types.Content(role="user",parts=[types.Part(text="Hello world!")]))asyncformessageinsession.receive():# Periodically, the server will send update messages that may# contain a handle for the current state of the session.ifmessage.session_resumption_update:update=message.session_resumption_updateifupdate.resumableandupdate.new_handle:# The handle should be retained and linked to the session.returnupdate.new_handle# For the purposes of this example, placeholder input is continually fed# to the model. In non-sample code, the model inputs would come from# the user.ifmessage.server_contentandmessage.server_content.turn_complete:breakif__name__=="__main__":asyncio.run(main())
جاوا اسکریپت
import{GoogleGenAI,Modality}from'@google/genai';constai=newGoogleGenAI({});constmodel='gemini-live-2.5-flash-preview';asyncfunctionlive(){constresponseQueue=[];asyncfunctionwaitMessage(){letdone=false;letmessage=undefined;while(!done){message=responseQueue.shift();if(message){done=true;}else{awaitnewPromise((resolve)=>setTimeout(resolve,100));}}returnmessage;}asyncfunctionhandleTurn(){constturns=[];letdone=false;while(!done){constmessage=awaitwaitMessage();turns.push(message);if(message.serverContent && message.serverContent.turnComplete){done=true;}}returnturns;}console.debug('Connecting to the service with handle %s...',previousSessionHandle)constsession=awaitai.live.connect({model:model,callbacks:{onopen:function(){console.debug('Opened');},onmessage:function(message){responseQueue.push(message);},onerror:function(e){console.debug('Error:',e.message);},onclose:function(e){console.debug('Close:',e.reason);},},config:{responseModalities:[Modality.TEXT],sessionResumption:{handle:previousSessionHandle}// The handle of the session to resume is passed here, or else null to start a new session.}});constinputTurns='Hello how are you?';session.sendClientContent({turns:inputTurns});constturns=awaithandleTurn();for(constturnofturns){if(turn.sessionResumptionUpdate){if(turn.sessionResumptionUpdate.resumable && turn.sessionResumptionUpdate.newHandle){letnewHandle=turn.sessionResumptionUpdate.newHandle// ...Store newHandle and start new session with this handle here}}}session.close();}asyncfunctionmain(){awaitlive().catch((e)=>console.error('got error',e));}main();
دریافت پیام قبل از قطع شدن جلسه
سرور یک پیام GoAway ارسال می کند که سیگنال می دهد که اتصال فعلی به زودی قطع خواهد شد. این پیام شامل timeLeft است که زمان باقیمانده را نشان میدهد و به شما امکان میدهد تا قبل از اینکه اتصال بهعنوان ABORTED قطع شود، اقدامات بیشتری انجام دهید.
پایتون
asyncforresponseinsession.receive():ifresponse.go_awayisnotNone:# The connection will soon be terminatedprint(response.go_away.time_left)
تاریخ آخرین بهروزرسانی 2025-08-22 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-08-22 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Session management with Live API\n\nIn the Live API, a session refers to a persistent\nconnection where input and output are streamed continuously over the same\nconnection (read more about [how it works](/gemini-api/docs/live)).\nThis unique session design enables low latency and supports unique features, but\ncan also introduce challenges, like session time limits, and early termination.\nThis guide covers strategies for overcoming the session management challenges\nthat can arise when using the Live API.\n\nSession lifetime\n----------------\n\nWithout compression, audio-only sessions are limited to 15 minutes,\nand audio-video sessions are limited to 2 minutes. Exceeding these limits\nwill terminate the session (and therefore, the connection), but you can use\n[context window compression](#context-window-compression) to extend sessions to\nan unlimited amount of time.\n\nThe lifetime of a connection is limited as well, to around 10 minutes. When the\nconnection terminates, the session terminates as well. In this case, you can\nconfigure a single session to stay active over multiple connections using\n[session resumption](#session-resumption).\nYou'll also receive a [GoAway message](#goaway-message) before the\nconnection ends, allowing you to take further actions.\n\nContext window compression\n--------------------------\n\nTo enable longer sessions, and avoid abrupt connection termination, you can\nenable context window compression by setting the [contextWindowCompression](/api/live#BidiGenerateContentSetup.FIELDS.ContextWindowCompressionConfig.BidiGenerateContentSetup.context_window_compression)\nfield as part of the session configuration.\n\nIn the [ContextWindowCompressionConfig](/api/live#contextwindowcompressionconfig), you can configure a\n[sliding-window mechanism](/api/live#ContextWindowCompressionConfig.FIELDS.ContextWindowCompressionConfig.SlidingWindow.ContextWindowCompressionConfig.sliding_window)\nand the [number of tokens](/api/live#ContextWindowCompressionConfig.FIELDS.int64.ContextWindowCompressionConfig.trigger_tokens)\nthat triggers compression. \n\n### Python\n\n from google.genai import types\n\n config = types.LiveConnectConfig(\n response_modalities=[\"AUDIO\"],\n context_window_compression=(\n # Configures compression with default parameters.\n types.ContextWindowCompressionConfig(\n sliding_window=types.SlidingWindow(),\n )\n ),\n )\n\n### JavaScript\n\n const config = {\n responseModalities: [Modality.AUDIO],\n contextWindowCompression: { slidingWindow: {} }\n };\n\nSession resumption\n------------------\n\nTo prevent session termination when the server periodically resets the WebSocket\nconnection, configure the [sessionResumption](/api/live#BidiGenerateContentSetup.FIELDS.SessionResumptionConfig.BidiGenerateContentSetup.session_resumption)\nfield within the [setup configuration](/api/live#BidiGenerateContentSetup).\n\nPassing this configuration causes the\nserver to send [SessionResumptionUpdate](/api/live#SessionResumptionUpdate)\nmessages, which can be used to resume the session by passing the last resumption\ntoken as the [`SessionResumptionConfig.handle`](/api/live#SessionResumptionConfig.FIELDS.string.SessionResumptionConfig.handle)\nof the subsequent connection.\n\nResumption tokens are valid for 2 hr after the last sessions termination. \n\n### Python\n\n import asyncio\n from google import genai\n from google.genai import types\n\n client = genai.Client()\n model = \"gemini-live-2.5-flash-preview\"\n\n async def main():\n print(f\"Connecting to the service with handle {previous_session_handle}...\")\n async with client.aio.live.connect(\n model=model,\n config=types.LiveConnectConfig(\n response_modalities=[\"AUDIO\"],\n session_resumption=types.SessionResumptionConfig(\n # The handle of the session to resume is passed here,\n # or else None to start a new session.\n handle=previous_session_handle\n ),\n ),\n ) as session:\n while True:\n await session.send_client_content(\n turns=types.Content(\n role=\"user\", parts=[types.Part(text=\"Hello world!\")]\n )\n )\n async for message in session.receive():\n # Periodically, the server will send update messages that may\n # contain a handle for the current state of the session.\n if message.session_resumption_update:\n update = message.session_resumption_update\n if update.resumable and update.new_handle:\n # The handle should be retained and linked to the session.\n return update.new_handle\n\n # For the purposes of this example, placeholder input is continually fed\n # to the model. In non-sample code, the model inputs would come from\n # the user.\n if message.server_content and message.server_content.turn_complete:\n break\n\n if __name__ == \"__main__\":\n asyncio.run(main())\n\n### JavaScript\n\n import { GoogleGenAI, Modality } from '@google/genai';\n\n const ai = new GoogleGenAI({});\n const model = 'gemini-live-2.5-flash-preview';\n\n async function live() {\n const responseQueue = [];\n\n async function waitMessage() {\n let done = false;\n let message = undefined;\n while (!done) {\n message = responseQueue.shift();\n if (message) {\n done = true;\n } else {\n await new Promise((resolve) =\u003e setTimeout(resolve, 100));\n }\n }\n return message;\n }\n\n async function handleTurn() {\n const turns = [];\n let done = false;\n while (!done) {\n const message = await waitMessage();\n turns.push(message);\n if (message.serverContent && message.serverContent.turnComplete) {\n done = true;\n }\n }\n return turns;\n }\n\n console.debug('Connecting to the service with handle %s...', previousSessionHandle)\n const session = await ai.live.connect({\n model: model,\n callbacks: {\n onopen: function () {\n console.debug('Opened');\n },\n onmessage: function (message) {\n responseQueue.push(message);\n },\n onerror: function (e) {\n console.debug('Error:', e.message);\n },\n onclose: function (e) {\n console.debug('Close:', e.reason);\n },\n },\n config: {\n responseModalities: [Modality.TEXT],\n sessionResumption: { handle: previousSessionHandle }\n // The handle of the session to resume is passed here, or else null to start a new session.\n }\n });\n\n const inputTurns = 'Hello how are you?';\n session.sendClientContent({ turns: inputTurns });\n\n const turns = await handleTurn();\n for (const turn of turns) {\n if (turn.sessionResumptionUpdate) {\n if (turn.sessionResumptionUpdate.resumable && turn.sessionResumptionUpdate.newHandle) {\n let newHandle = turn.sessionResumptionUpdate.newHandle\n // ...Store newHandle and start new session with this handle here\n }\n }\n }\n\n session.close();\n }\n\n async function main() {\n await live().catch((e) =\u003e console.error('got error', e));\n }\n\n main();\n\nReceiving a message before the session disconnects\n--------------------------------------------------\n\nThe server sends a [GoAway](/api/live#GoAway) message that signals that the current\nconnection will soon be terminated. This message includes the [timeLeft](/api/live#GoAway.FIELDS.google.protobuf.Duration.GoAway.time_left),\nindicating the remaining time and lets you take further action before the\nconnection will be terminated as ABORTED. \n\n### Python\n\n async for response in session.receive():\n if response.go_away is not None:\n # The connection will soon be terminated\n print(response.go_away.time_left)\n\n### JavaScript\n\n const turns = await handleTurn();\n\n for (const turn of turns) {\n if (turn.goAway) {\n console.debug('Time left: %s\\n', turn.goAway.timeLeft);\n }\n }\n\nReceiving a message when the generation is complete\n---------------------------------------------------\n\nThe server sends a [generationComplete](/api/live#BidiGenerateContentServerContent.FIELDS.bool.BidiGenerateContentServerContent.generation_complete)\nmessage that signals that the model finished generating the response. \n\n### Python\n\n async for response in session.receive():\n if response.server_content.generation_complete is True:\n # The generation is complete\n\n### JavaScript\n\n const turns = await handleTurn();\n\n for (const turn of turns) {\n if (turn.serverContent && turn.serverContent.generationComplete) {\n // The generation is complete\n }\n }\n\nWhat's next\n-----------\n\nExplore more ways to work with the Live API in the full\n[Capabilities](/gemini-api/docs/live) guide,\nthe [Tool use](/gemini-api/docs/live-tools) page, or the\n[Live API cookbook](https://colab.research.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Get_started_LiveAPI.ipynb)."]]