å°ãåãŸã§ãå€§èŠæš¡ãªASP.NETãããžã§ã¯ãã®éçºã®äžç°ãšããŠã次ã®ãµãã¿ã¹ã¯ãçºçããŸããããªã¢ã«ã¿ã€ã ã§æŽæ°ããã衚圢åŒããŒã¿ã®èŠèŠè¡šç€ºãå®è£
ããããšã§ãã æŽæ°ã¹ããŒã ã¯éåžžã«åçŽã§ããã€ãŸããããŒã¿ã¯QueryStringãä»ããŠãµãŒããŒã«éä¿¡ãããŸããããã«ãããããŒãžäžã®å€ãããŒã¿ãã§ããã ãæ©ããããŒãžãªãã§ããŒãžãæŽæ°ããããšãªã眮ãæããå¿
èŠããããŸãã ç§ãããã«æãã€ããæåã®è§£æ±ºçã¯ãã¿ã€ããŒAJAXãªã¯ãšã¹ãã®ç¢ºç«ããããã¯ããã¯ããããšãã°5ç§ããšã«äœ¿çšããããšã§ããã ãããããã®ã¢ãããŒããé©çšããããšã®æãããªæ¬ ç¹ã¯ããã«æããã«ãªããŸããïŒãŸããããªãã®æ°ã®æœåšçãªã¯ã©ã€ã¢ã³ããæ¯åæ°ããæ¥ç¶ãäœæãããã³ã«5ç§ããšã«ãµãŒããŒããŽããŽãåãããŸããçµå±ã®ãšãããä»®æ³çã«ã¯ãããŒã¿ã¯1ç§ãããæ°åã§ããµãŒããŒã«å°çããå¯èœæ§ããããŸãïŒãŸãã¯ãæ°åã§ãå°çããªãå ŽåããããŸããããã¯ãæåãã®å Žåã§ãïŒã
ãã®ãœãªã¥ãŒã·ã§ã³ã®ã¢ã€ãã¢ã¯ãWebãã£ãããäœæããããã®Perlã§ã®Cometãã¯ãããžãŒã®å®è£
ã«ã€ããŠèª¬æ
ããHabréã®èšäºãž
ã®ãªã³ã¯ãå
±æããååããæããããªãæãã€ãããã®ã§ãã ã
åœæã¯ããªããå¿
èŠãšãããã®ã§ãïŒ ããšç§ãã¡ã¯èããç§ã¯ãã®ããšãASP.NETã«ããèŸŒãæ¹æ³ãèŠã€ãå§ããŸããã å®éã«ã¯ãã«ããã®äžã§äœãè°è«ãããŸããã
ãŸããCometãšã¯äœããèããŸãããã ãŠã£ãããã£ã¢ãããã«ã€ããŠç§ãã¡ã«äŒããŠããããšã¯æ¬¡ã®ãšããã§ãã
Comet ïŒWebéçºïŒã¯ãWebã¢ããªã±ãŒã·ã§ã³ã®ã¢ãã«ã説æããæ°èªã§ããHTTPæ¥ç¶ã䜿çšãããšãWebãµãŒããŒã¯ããã©ãŠã¶ãŒããã®è¿œå èŠæ±ãªãã«ãã©ãŠã¶ãŒã«ããŒã¿ãããã·ã¥ã§ããŸãã ã³ã¡ããã¯ããã®çžäºäœçšãéæããããã®ããŸããŸãªææ³ã瀺ãããã«äœ¿çšããããã€ããŒããŒã ã§ãã ãããã®ã¡ãœããã®å
±éç¹ã¯ãç¬èªã®ãã©ã°ã€ã³ã§ã¯ãªããJavaScriptãªã©ã®ãã©ãŠã¶ãŒã§çŽæ¥ãµããŒããããŠãããã¯ãããžãŒã«åºã¥ããŠããããšã§ãã çè«çã«ã¯ãCometã®ã¢ãããŒãã¯ããã©ãŠã¶ãããŒãžãæŽæ°ããããã«ããŒãžå
šäœãŸãã¯äžéšãèŠæ±ããWorld Wide Webã®å
ã®æŠå¿µãšã¯ç°ãªããŸãã ãã ããå®éã«ã¯ãCometã¢ããªã±ãŒã·ã§ã³ã¯éåžž
ãé·ãããŒãªã³ã°ã§Ajaxã䜿çšããŠãµãŒããŒäžã®æ°ããæ
å ±ã確èªããŸãã
ã§ãããããã®å®çŸ©ããç§ãã¡ããšããããŒã¯ãŒãã¯ãAjax with long pollingãã§ãã ããã¯äœã§ãäœãšäžç·ã«é£ã¹ãããŸããïŒ ããã³ã°ããŒãªã³ã°ããã¯ãããžãŒã䜿çšããå Žåãã¯ã©ã€ã¢ã³ãã¯ãµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ãã...åŸ
æ©ããŸãã ãµãŒããŒã«æ°ããããŒã¿ã衚瀺ãããã®ãåŸ
ã¡ãŸãã ããŒã¿ãå°çãããšããµãŒããŒã¯ãã®ããŒã¿ãã¯ã©ã€ã¢ã³ãã«éä¿¡ãããã®åŸãæ°ãããªã¯ãšã¹ããéä¿¡ããŠåã³åŸ
æ©ããŸãã ããšã³ãã¬ã¹ãªã¯ãšã¹ããã®ä»£æ¿æè¡ãããšãã°ããããã ãForever iframeãïŒ
ããã§ããå°ãèªãããšãã§ã
ãŸã ïŒã¯ãåžžã«é©çšã§ãããã®ãšã¯ã»ã©é ãã§ãã ã¿ã€ã ã¢ãŠããªã©ããããŸã§èª°ããã£ã³ã»ã«ããŠããŸããã
ãŸããã¿ã¹ã¯ã¯éåžžã«æç¢ºã§ã-å©çšå¯èœãªããŒã«ïŒAJAX + ASP.NETïŒã§äžèšã®é·ãããŒãªã³ã°ãå®è£
ããå¿
èŠããããŸãã ããã¯æåã®åé¡ã«ã€ãªãããŸããã€ãŸãããµãŒããŒã«é¡§å®¢ã«éä¿¡ã§ããæ°ããããŒã¿ããããŸã§ïŒãããŠæããã«è€æ°ã®ã¯ã©ã€ã¢ã³ãããããŸã§ïŒãçä¿¡èŠæ±ãä¿åããå¿çãæäŸããªãæ¹æ³ã§ãã ãããŠãããã§éåæHTTPãã³ãã©ãŒãå©ãã«ãªããŸãã
public interface IHttpAsyncHandler : IHttpHandler
{
IAsyncResult BeginProcessRequest( HttpContext ctx,
AsyncCallback cb,
object obj);
void EndProcessRequest(IAsyncResult ar);
}
* This source code was highlighted with Source Code Highlighter .
IHttpHandlerã€ã³ã¿ãŒãã§ã€ã¹ããã§ã¯ãªããIHttpAsyncHandlerããã¯ã©ã¹ãç¶æ¿ããŸããIHttpAsyncHandlerã¯ã䜿ãæ
£ããProcessRequestã¡ãœãããšå
±ã«BeginProcessRequestãšEndProcessRequestã®2ã€ã®æ°ããã¡ãœãããæäŸããŸãã ç¹ã«ãæåã®ãã®ã«èå³ããããŸãããªããªãã ã€ãŸãããªã¯ãšã¹ãã®åŠçã®éå§æã«ããã®ãªã¯ãšã¹ããæã§ååŸããå¿
èŠããããXãæ¥ããŸã§æŸããªãã§ãã ããã ã芧ã®ãšãããBeginProcessRequestã¯IAsyncResultã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ãããªããžã§ã¯ããè¿ããŸãã
public interface IAsyncResult
{
public object AsyncState { get ; }
public bool CompletedSynchronously { get ; }
public bool IsCompleted { get ; }
public WaitHandle AsyncWaitHandle { get ; }
}
* This source code was highlighted with Source Code Highlighter .
æå®ãããã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããæ°ããã¯ã©ã¹ãäœæããBeginProcessRequestã«éä¿¡ãããèŠæ±ããŒã¿ãšç¬èªã®clientGuidãã©ã¡ãŒã¿ãŒã®ãªããžããªãšããŠãæ©èœããŸããããã¯ããµãŒããŒã«æ¥ç¶ããã¯ã©ã€ã¢ã³ãã®äžæã®èå¥åãšããŠå°æ¥äœ¿çšããäœããã®æ¹æ³ã§èŠæ±ãèå¥ããŸãã
public class CometAsyncRequestState : IAsyncResult
{
private HttpContext _currentContext;
private AsyncCallback _asyncCallback;
private Object _extraData;
private Boolean _isCompleted;
private Guid _clientGuid;
private ManualResetEvent _callCompleteEvent = null ;
public CometAsyncRequestState( HttpContext currentContext, AsyncCallback asyncCallback, Object extraData)
{
_currentContext = currentContext;
_asyncCallback = asyncCallback;
_extraData = extraData;
_isCompleted = false ;
}
public void CompleteRequest()
{
_isCompleted = true ;
lock ( this )
{
if (_callCompleteEvent != null )
_callCompleteEvent.Set();
}
if (_asyncCallback != null )
{
_asyncCallback( this );
}
}
public HttpContext CurrentContext
{
get
{
return _currentContext;
}
set
{
_currentContext = value ;
}
}
public AsyncCallback AsyncCallback
{
get
{
return _asyncCallback;
}
set
{
_asyncCallback = value ;
}
}
public Object ExtraData
{
get
{
return _extraData;
}
set
{
_extraData = value ;
}
}
public Guid ClientGuid
{
get
{
return _clientGuid;
}
set
{
_clientGuid = value ;
}
}
// IAsyncResult implementations
public Boolean CompletedSynchronously
{
get
{
return false ;
}
}
public Boolean IsCompleted
{
get
{
return _isCompleted;
}
}
public Object AsyncState
{
get
{
return _extraData;
}
}
public WaitHandle AsyncWaitHandle
{
get
{
lock ( this )
{
if (_callCompleteEvent == null )
_callCompleteEvent = new ManualResetEvent( false );
return _callCompleteEvent;
}
}
}
}
* This source code was highlighted with Source Code Highlighter .
ã芧ã®ãšãããCompleteRequest颿°ãåŒã³åºããŸã§ããªã¯ãšã¹ãã¯å®äºãããšèŠãªãããŸããã çŽ æŽããã-ãããå¿
èŠã§ãã ãããã®çä¿¡ãªã¯ãšã¹ããä¿åããå Žæã¯ã©ããã«ã®ã¿æ®ã£ãŠããŸãã ãã®é¢æ°ããã³ãªã¯ãšã¹ãåŠç颿°ã«å¯ŸããŠãéçã¯ã©ã¹CometClientProcessorãäœæããŸãã
public static class CometClientProcessor
{
private static Object _lockObj;
private static List <CometAsyncRequestState> _clientStateList;
static CometClientProcessor()
{
_lockObj = new Object();
_clientStateList = new List <CometAsyncRequestState>();
}
public static void PushData( String pushedData)
{
List <CometAsyncRequestState> currentStateList = new List <CometAsyncRequestState>();
lock (_lockObj)
{
foreach (CometAsyncRequestState clientState in _clientStateList)
{
currentStateList.Add(clientState);
}
}
foreach (CometAsyncRequestState clientState in currentStateList)
{
if (clientState.CurrentContext.Session != null )
{
clientState.CurrentContext.Response.Write(pushedData);
clientState.CompleteRequest();
}
}
}
public static void AddClient(CometAsyncRequestState state)
{
Guid newGuid;
lock (_lockObj)
{
while ( true )
{
newGuid = Guid .NewGuid();
if (_clientStateList.Find(s => s.ClientGuid == newGuid) == null )
{
state.ClientGuid = newGuid;
break ;
}
}
_clientStateList.Add(state);
}
}
public static void UpdateClient(CometAsyncRequestState state, String clientGuidKey)
{
Guid clientGuid = new Guid (clientGuidKey);
lock (_lockObj)
{
CometAsyncRequestState foundState = _clientStateList.Find(s => s.ClientGuid == clientGuid);
if (foundState != null )
{
foundState.CurrentContext = state.CurrentContext;
foundState.ExtraData = state.ExtraData;
foundState.AsyncCallback = state.AsyncCallback;
}
}
}
public static void RemoveClient(CometAsyncRequestState state)
{
lock (_lockObj)
{
_clientStateList.Remove(state);
}
}
}
* This source code was highlighted with Source Code Highlighter .
CometClientProcessorã«ã¯ãçŸåšä¿æãããŠãããªã¯ãšã¹ãã®ãªã¹ãããªã¯ãšã¹ãã远å ããããã®AddClient颿°ïŒæ°ããã¯ã©ã€ã¢ã³ããæ¥ç¶ããå ŽåïŒããªã¯ãšã¹ããæŽæ°ããããã®UpdateClientïŒæ¢ã«æ¥ç¶ãããŠããã¯ã©ã€ã¢ã³ããæ°ãããªã¯ãšã¹ããéä¿¡ããå ŽåïŒãããã³ãªã¯ãšã¹ããåé€ããããã®RemoveClientïŒã¯ã©ã€ã¢ã³ããåæããå ŽåïŒãã¡ã€ã³PushDataã¡ãœããã ããããããããããã«ãæãåçŽãªããŒã¿ãã€ãŸãURLã®ãã©ã¡ãŒã¿ãŒãä»ããŠãµãŒããŒã«éãããè¡ããããã·ã¥ãããŸãã ã芧ã®ãšããããã¹ãŠãéåžžã«åçŽã§ããçŸåšä¿æãããŠããèŠæ±ãå®è¡ãããµãŒããŒããã®ããŒã¿ãå¿çã«æžã蟌ã¿ãCompleteRequest颿°ãåŒã³åºããŠãèŠæ±ãè§£æŸããã¯ã©ã€ã¢ã³ãã«å¿çãéä¿¡ããŸãã ãã®äŸã§ã¯ãå¯äžã®ããŒãžã®Page_Load颿°ããPushDataåŒã³åºããè¡ãããŸãã
protected void Page_Load( object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Request.QueryString[ "x" ] != null )
{
CometClientProcessor.PushData(Request.QueryString[ "x" ].ToString());
}
}
}
* This source code was highlighted with Source Code Highlighter .
åè¿°ã®ããã«ãããŒã¿ã¯URLã®ãã©ã¡ãŒã¿ãŒãä»ããŠååŸãããŸãããã®å Žåãããããããããããã«ãxããšåŒã°ããŸãã ãµãŒããŒéšåã§ã¯ãå®éã«ã¯éåæãã³ãã©ãŒèªäœãå®è£
ããã ãã§ãã ããããæåã«ãã¯ã©ã€ã¢ã³ãéšåã«ç®ãåããŠïŒjQueryã©ã€ãã©ãªãŒã®å©ããªãã§ã¯ãªãïŒããã€ãã®ããªãæ®éã®JavaScript颿°ãäœæããŸãããã
var clientGuid
$( document ).ready( function () {
var str = window.location.href;
if (str.indexOf( "?" ) < 0)
Connect();
});
$(window).unload( function () {
var str = window.location.href;
if (str.indexOf( "?" ) < 0)
Disconnect();
});
function SendRequest() {
var url = './CometAsyncHandler.ashx?cid=' + clientGuid;
$.ajax({
type: "POST" ,
url: url,
success: ProcessResponse,
error: SendRequest
});
}
function Connect() {
var url = './CometAsyncHandler.ashx?cpsp=CONNECT' ;
$.ajax({
type: "POST" ,
url: url,
success: OnConnected,
error: ConnectionRefused
});
}
function Disconnect() {
var url = './CometAsyncHandler.ashx?cpsp=DISCONNECT' ;
$.ajax({
type: "POST" ,
url: url
});
}
function ProcessResponse(transport) {
$( "#contentWrapper" ).html(transport);
SendRequest();
}
function OnConnected(transport) {
clientGuid = transport;
SendRequest();
}
function ConnectionRefused() {
$( "#contentWrapper" ).html( "Unable to connect to Comet server. Reconnecting in 5 seconds..." );
setTimeout(Connect(), 5000);
}
* This source code was highlighted with Source Code Highlighter .
ããã¥ã¡ã³ããèªã¿èŸŒãŸãããšããã«ãURLã§ãã©ã¡ãŒã¿ãŒã®ååšã確èªãïŒãã©ã¡ãŒã¿ãŒåãããURLãããäžåºŠãç¥ããããŸã-ããã¯ããã·ã¥ã®ããã«ãµãŒããŒã«ããŒã¿ãéä¿¡ããŠããŸãïŒãConnect颿°ãåŒã³åºããŸãã ããã¯ãé çªã«ããã§ã«ãã³ãã©ãŒãšã®éä¿¡ãéå§ããŠããŸãã ããããããããã«ãã¢ã¯ã·ã§ã³ãå®çŸ©ãããµãŒãã¹ã¯ãŒãïŒCONNECT / DISCONNECTïŒã¯ãcpspãã©ã¡ãŒã¿ãŒãä»ããŠæž¡ãããŸãã ãããã£ãŠãConnectã¯ãµãŒããŒã§AddClientåŒã³åºããéå§ããDisconnect-RemoveClientãéå§ããå¿
èŠããããŸãã æ¥ç¶ã確ç«ãããã¯ã©ã€ã¢ã³ããclientGuidãåä¿¡ãããšãSendRequest颿°ãåŒã³åºãããŸããããã¯ãã¯ã©ã€ã¢ã³ããæ¥ç¶ãåæããããšã決å®ãããŸã§ãµãŒããŒãããã³ã°ãã£ã«ãããŸãã åSendRequeståŒã³åºãã¯ããµãŒããŒäžã§UpdateClient颿°ã®å®è¡ãéå§ãããã®ã¯ã©ã€ã¢ã³ãã¯ã³ã³ããã¹ããšã³ãŒã«ããã¯ãæŽæ°ããŸãã
ããŠãã»ãšãã©ãã¹ãŠã®æºåãæŽã£ãã®ã§ãäžèšã®ã¡ã«ããºã å
šäœã®äžæ žã§ããéåæãã³ãã©ãŒãå®è£
ãããšããæ¥ãŸããã
public enum ConnectionCommand
{
CONNECT,
DISCONNECT
}
public static class ConnectionProtocol
{
public static String PROTOCOL_GET_PARAMETER_NAME = "cpsp" ;
public static String CLIENT_GUID_PARAMETER_NAME = "cid" ;
}
* This source code was highlighted with Source Code Highlighter .
<%@ WebHandler Language= "C#" Class= "CometAsyncHandler" %>
using System;
using System.Web;
using DevelopMentor;
public class CometAsyncHandler : IHttpAsyncHandler, System.Web.SessionState.IRequiresSessionState
{
static private ThreadPool _threadPool;
static CometAsyncHandler()
{
_threadPool = new ThreadPool(2, 50, "Comet Pool" );
_threadPool.PropogateCallContext = true ;
_threadPool.PropogateThreadPrincipal = true ;
_threadPool.PropogateHttpContext = true ;
_threadPool.Start();
}
public IAsyncResult BeginProcessRequest( HttpContext ctx, AsyncCallback cb, Object obj)
{
CometAsyncRequestState currentAsyncRequestState = new CometAsyncRequestState(ctx, cb, obj);
_threadPool.PostRequest( new WorkRequestDelegate(ProcessServiceRequest), currentAsyncRequestState);
return currentAsyncRequestState;
}
private void ProcessServiceRequest(Object state, DateTime requestTime)
{
CometAsyncRequestState currentAsyncRequestState = state as CometAsyncRequestState;
if (currentAsyncRequestState.CurrentContext.Request.QueryString[ConnectionProtocol.PROTOCOL_GET_PARAMETER_NAME] ==
ConnectionCommand.CONNECT.ToString())
{
CometClientProcessor.AddClient(currentAsyncRequestState);
currentAsyncRequestState.CurrentContext.Response.Write(currentAsyncRequestState.ClientGuid.ToString());
currentAsyncRequestState.CompleteRequest();
}
else if (currentAsyncRequestState.CurrentContext.Request.QueryString[ConnectionProtocol.PROTOCOL_GET_PARAMETER_NAME] ==
ConnectionCommand.DISCONNECT.ToString())
{
CometClientProcessor.RemoveClient(currentAsyncRequestState);
currentAsyncRequestState.CompleteRequest();
}
else
{
if (currentAsyncRequestState.CurrentContext.Request.QueryString[ConnectionProtocol.CLIENT_GUID_PARAMETER_NAME] != null )
{
CometClientProcessor.UpdateClient(currentAsyncRequestState,
currentAsyncRequestState.CurrentContext.Request.QueryString[ConnectionProtocol.CLIENT_GUID_PARAMETER_NAME].ToString());
}
}
}
public void EndProcessRequest(IAsyncResult ar)
{
}
public void ProcessRequest( HttpContext context)
{
}
public bool IsReusable
{
get
{
return true ;
}
}
}
* This source code was highlighted with Source Code Highlighter .
äžèšã®ãã¹ãŠã®åŸãæ³šææ·±ãèªè
ãæã€ãããããªãå¯äžã®è³ªåã¯ããã«ã¹ã¿ã ã¹ã¬ããããŒã«ã䜿çšããçç±ãã§ãã å®å
šã«æããã§ã¯ãããŸããããçãã¯éåžžã«åçŽã§ããASP.NETãã¬ããããŒã«ã®ã¯ãŒã¯ãããŒãã§ããã ãæ©ããè§£æŸãããŠãçä¿¡èŠæ±ã®åŠçãç¶ç¶ããèŠæ±ã®çŽæ¥åŠçããå
éšãã¹ã¬ããã«è»¢éã§ããããã«ããããã§ãã ãããè¡ãããªãå Žåãååãªæ°ã®çä¿¡èŠæ±ããããšãäžèŠãããšããäžèŠéŠ¬é¹¿ãããã®ã£ã°ããçºçããå¯èœæ§ããããŸãããASP.NETã¯ã¯ãŒã¯ãããŒã䜿ãæãããŸãããã åãçç±ã§ãBeginInvokeã¡ãœãããŸãã¯æšæºã®ã¹ã¬ããããŒã«ã¡ãœããThreadPool.QueueUserWorkItemã«ãã£ãŠå±èµ·ãããéåæããªã²ãŒãã䜿çšããããšã¯ã§ããŸããã ã©ã¡ãã®å Žåããã¹ã¬ããã¯åãASP.NETãã¬ãããã«ããåé€ããããç³é¹žã§çž«ãä»ãããããç¶æ³ã«ãªããŸãã ãã®äŸã§ã¯ãMike Woodringã«ãã£ãŠå®è£
ãããã«ã¹ã¿ã ã¹ã¬ããããŒã«ã䜿çšãããŸãã ãããšåœŒã®ä»ã®å€ãã®çºå±ã¯
ããã§èŠãã
ãŸã ã
åºæ¬çã«ã¯ä»¥äžã§ãã åœåã®ããã«é£ããã¯ãããŸããã§ããã ã¯ã©ã€ã¢ã³ãã¯Default.aspxãåŒã³åºããŠCometãµãŒããŒã«æ¥ç¶ããGETãã©ã¡ãŒã¿ãŒala Default.aspxïŒX = Happy_New_YearãåãããŒãžã«æž¡ãããšã§ããŒã¿ãããã·ã¥ããŸãã æ®å¿µãªããããã®ã¢ãããŒãã®ã¹ã±ãŒã©ããªãã£ã®å€§èŠæš¡ãªãã¹ãã¯ãŸã å¯èœã§ã¯ãããŸããããã ãããããã«ã€ããŠã¢ã€ãã¢ãæã£ãŠãããªããæžããŠãæ¥ããããããªãã§ãã ããã
ãæž
èŽããããšãããããŸããã
UPD ãµã³ãã«ãããžã§ã¯ãã®ãªã³ã¯ã
ã¢ãŒã«ã€ãã«è¿œå ã
ãŸã ïŒã30 KBïŒã è¡šç€ºæ¹æ³ïŒVSã§ã¯ãCometPage.aspxãã¹ã¿ãŒãããŒãžãšããŠèšå®ããèµ·åãããã©ãŠã¶ãŒ/ãã©ãŠã¶ãŒã§åãURLã§è€æ°ã®ã¿ããéãïŒãããã®ãã©ãŠã¶ãŒã§ã®åææ¥ç¶æ°ã®å¶éãèŠããŠããã ã
ã§ã ïŒããã©ã¡ãŒã¿ãŒã远å ããŸã
ãïŒX = [any_text]ãéããéããŠãããã¹ãŠã®ã¿ãã§ãã©ã¡ãŒã¿ãŒã®å€ãã©ã®ããã«è¡šç€ºããããã確èªããŸãã