Copy link to clipboard
Copied
Hi All,
TL;DR: Basically not sure how to stream text to the browser from a CFC.
I'm sure this is either simple or not possible but how do you return a Server Side Event text stream, using cfcontent type="text/event-stream" from a CFC function as opposed to a .cfm page?
I currently have a this code sample set up in a getmessages.cfm page and it works as expected:
<cfscript>
cfheader( name="cache-control", value="no-cache, no-store, must-revalidate" );
cfheader( name="pragma", value="no-cache" );
cfheader( name="expires", value=getHttpTimeString(now()) );
cfcontent( type="text/event-stream" );
cfsetting( requesttimeout=60 );
for ( i=1 ; i<=10 ; i++ ) {
// end each data line with two #Chr(10)#
if ( i == 1 ) {
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("data: {""msg"": ""Starting Process..."", ""id"": #i#} #Chr(10)##Chr(10)#");
}
writeOutput("retry: 10000#Chr(10)#");
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("data: {""msg"": ""#i# #timeFormat(now(), 'medium')#"", ""id"": #i#}#Chr(10)##Chr(10)#");
if ( i == 10 ) {
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("data: {""msg"": ""Ending Process..."", ""id"": #i#} #Chr(10)##Chr(10)#");
}
cfflush();
sleep(2000);
}
// send zipCreated custom event
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("event: zipCreated#Chr(10)#");
writeOutput("data: {""msg"": ""Zip Created."", ""id"": #i#} #Chr(10)##Chr(10)#");
</cfscript>
I am wondering how to do the same thing except from a CFC function instead. So currently to consume this in a javascript file I use:
var source = new EventSource("getMessages.cfm", {
withCredentials: true,
});
And instead I would like to be calling assuming the code was in the getMessages method:
var source = new EventSource("MyCFC.cfc?method=getMessages&returnFormat=plain", {
withCredentials: true,
});
Is this possible?
1 Correct answer
Create the method getMessage with output attribute set to true.
Something like:
/* MyCFC.cfc */
component {
void function getMessage() output=true {
cfheader( name="cache-control", value="no-cache, no-store, must-revalidate" );
cfheader( name="pragma", value="no-cache" );
cfheader( name="expires", value=getHttpTimeString(now()) );
cfcontent( type="text/event-stream" );
cfsetting( requesttimeout=60 );
for ( i=1 ; i<=10 ; i++ ) {
// end each data line with
...
Copy link to clipboard
Copied
Create the method getMessage with output attribute set to true.
Something like:
/* MyCFC.cfc */
component {
void function getMessage() output=true {
cfheader( name="cache-control", value="no-cache, no-store, must-revalidate" );
cfheader( name="pragma", value="no-cache" );
cfheader( name="expires", value=getHttpTimeString(now()) );
cfcontent( type="text/event-stream" );
cfsetting( requesttimeout=60 );
for ( i=1 ; i<=10 ; i++ ) {
// end each data line with two #Chr(10)#
if ( i == 1 ) {
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("data: {""msg"": ""Starting Process..."", ""id"": #i#} #Chr(10)##Chr(10)#");
}
writeOutput("retry: 10000#Chr(10)#");
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("data: {""msg"": ""#i# #timeFormat(now(), 'medium')#"", ""id"": #i#}#Chr(10)##Chr(10)#");
if ( i == 10 ) {
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("data: {""msg"": ""Ending Process..."", ""id"": #i#} #Chr(10)##Chr(10)#");
}
cfflush();
sleep(2000);
}
// send zipCreated custom event
writeOutput("id: #createUUID()##Chr(10)#");
writeOutput("event: zipCreated#Chr(10)#");
writeOutput("data: {""msg"": ""Zip Created."", ""id"": #i#} #Chr(10)##Chr(10)#");
}
}
/* testPage.cfm (in same directory as MyCFC.cfc) */
<cfscript>
testObj=createobject("component", "MyCFC");
testObj.getMessage();
</cfscript>
Copy link to clipboard
Copied
Thanks! That seems to do the trick.

