Dans l'API Live, une session fait référence à une connexion persistante où les entrées et les sorties sont diffusées en continu sur la même connexion (pour en savoir plus, consultez Fonctionnement).
Cette conception de session unique permet une faible latence et prend en charge des fonctionnalités uniques, mais peut également poser des problèmes, comme des limites de temps de session et une résiliation anticipée.
Ce guide présente des stratégies permettant de surmonter les difficultés de gestion des sessions qui peuvent survenir lors de l'utilisation de l'API Live.
Durée de vie de la session
Sans compression, les sessions audio uniquement sont limitées à 15 minutes et les sessions audio et vidéo à 2 minutes. Si vous dépassez ces limites, la session (et donc la connexion) sera interrompue. Toutefois, vous pouvez utiliser la compression de la fenêtre de contexte pour prolonger les sessions indéfiniment.
La durée de vie d'une connexion est également limitée à environ 10 minutes. Lorsque la connexion se termine, la session se termine également. Dans ce cas, vous pouvez configurer une seule session pour qu'elle reste active sur plusieurs connexions à l'aide de la reprise de session.
Vous recevrez également un message GoAway avant la fin de la connexion, ce qui vous permettra de prendre d'autres mesures.
Compression de la fenêtre de contexte
Pour activer des sessions plus longues et éviter l'arrêt brutal de la connexion, vous pouvez activer la compression de la fenêtre de contexte en définissant le champ contextWindowCompression dans la configuration de la session.
Si vous transmettez cette configuration, le serveur envoie des messages SessionResumptionUpdate, qui peuvent être utilisés pour reprendre la session en transmettant le dernier jeton de reprise en tant que SessionResumptionConfig.handle de la connexion suivante.
Les jetons de reprise sont valides pendant deux heures après la fin de la dernière session.
Python
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())
JavaScript
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();
Recevoir un message avant la déconnexion de la session
Le serveur envoie un message GoAway indiquant que la connexion actuelle sera bientôt interrompue. Ce message inclut timeLeft, qui indique le temps restant et vous permet de prendre d'autres mesures avant que la connexion ne soit interrompue (ABORTED).
Python
asyncforresponseinsession.receive():ifresponse.go_awayisnotNone:# The connection will soon be terminatedprint(response.go_away.time_left)
Sauf indication contraire, le contenu de cette page est régi par une licence Creative Commons Attribution 4.0, et les échantillons de code sont régis par une licence Apache 2.0. Pour en savoir plus, consultez les Règles du site Google Developers. Java est une marque déposée d'Oracle et/ou de ses sociétés affiliées.
Dernière mise à jour le 2025/08/22 (UTC).
[[["Facile à comprendre","easyToUnderstand","thumb-up"],["J'ai pu résoudre mon problème","solvedMyProblem","thumb-up"],["Autre","otherUp","thumb-up"]],[["Il n'y a pas l'information dont j'ai besoin","missingTheInformationINeed","thumb-down"],["Trop compliqué/Trop d'étapes","tooComplicatedTooManySteps","thumb-down"],["Obsolète","outOfDate","thumb-down"],["Problème de traduction","translationIssue","thumb-down"],["Mauvais exemple/Erreur de code","samplesCodeIssue","thumb-down"],["Autre","otherDown","thumb-down"]],["Dernière mise à jour le 2025/08/22 (UTC)."],[],[],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)."]]